В моем приложении для Android мне нужно прочитать большой объем данных из набора файлов .ini, которые изначально (и до сих пор) были развернуты с помощью приложения Windows. Приложение связано с определенным аппаратным обеспечением, и основная цель файлов .ini - описать программные константы, данные в реальном времени и элементы пользовательского интерфейса, касающиеся аппаратного устройства.
Чтобы перейти к конкретному вопросу разработки Java, на котором я хотел бы помочь, вот пример того, как будет структурирована типичная строка данных из файла .ini. Обычно у нас есть имя параметра, за которым следуют различные столбцы строковых или числовых данных:
example = example, "example", "C", 0, 255, -1, -1, 256, 256
Каждая строка данных, которые я анализирую и маркирую, затем представляется в приложении как объект. Для создания каждого объекта из каждой строки данных файла .ini в настоящее время я использую интерфейс Builder / Fluent. Итак, приведенная выше строка приведет к созданию объекта следующим образом:
someObject.setName( t.s(2) ).setUnits( t.s(3) ).setLowerUpper( t.f(4), t.f(5) ) ...
t
- это мой экземпляр класса токенизатора, который использовался для разбора файла .ini, а его методы s(int)
и f(int)
являются геттерами, которые выбирают целое число или число с плавающей запятой для данного номера столбца.
Это немного грязно, потому что мой базовый класс обработки файлов .ini, который выполняет создание объектов на основе данных, возвращаемых токенизатором, должен содержать магические числа повсюду для столбцов строк. Я также должен позаботиться о том, чтобы использовать s()
или f()
в зависимости от ситуации (хотя компилятор, конечно, сообщит об ошибке, если я использую неправильную, основываясь на типах, требуемых моими установщиками объектов).
Что я действительно хотел бы сделать, так это иметь другой класс, который я мог бы назвать IniFileDefinitions. В идеале этот класс должен содержать перечисляемые определения для номеров строк и связанных с ними типов. Следовательно, при использовании этого класса создание объекта выше может выглядеть примерно так (псевдокод, очевидно):
someObject.setName( t.get(INI_NAME) ).setUnits( t.get(INI_UNITS) ).setLowerUpper( t.get(INI_LOWER), t.get(INI_UPPER) );
Я немного застрял в том, как я могу определить значение перечисления, которое я мог бы передать своему токенизатору, и чтобы токенизатор не только использовал это перечисление для определения номера столбца, но и изменял возвращаемый тип ( целое число, строка, число с плавающей точкой и т. д.) на основе этого перечисления.
Я понимаю, что перечисления Java довольно мощные, и для меня было бы возможно иметь два поля на перечисление, где первое поле дает номер строки, а второе поле описывает тип, например ::1010 *
public enum someIniEnumDefs{
INI_NAME( 2, INI_TYPE_STRING )
...
Мне пришло в голову, что одним из способов сделать эту работу было бы использование метода getter в моем токенизаторе, который мог бы варьировать тип, который он возвращает, в зависимости от того, какой тип enum говорит, что должен быть, но, очевидно, это невозможно в Java , Насколько я знаю, мне пришлось бы возвращать пользовательский объект, который содержит один из всех типов (string, integer, ...) или просто возвращать Object (тьфу). Мне не особо нравится ни одно из этих решений.
У меня была одна идея, что токенизатор может иметь несколько (перегруженных) методов значения get (), каждый из которых возвращает свой тип примитива. Какой именно метод get () будет вызван, может каким-то образом зависеть от моего поля 'type' в определениях enum. Я не думаю, что я смогу это сделать. Единственный способ, о котором я подумал, - это разделить мои перечисления на несколько групп, представляющих разные типы, и тогда мои методы get токенизатора будут перегружены следующим образом:
int get(SomeIniEnumDefs_Ints){ ... return someInt }
String get(SomeIniEnumDefs_Strings){ ... return someString }
...
Учитывая мой недостаток опыта с перечислениями Java (который, как я знаю, далеко, гораздо более мощный, чем то, к чему я привык в простом старом C!), Я знаю, что должен быть аккуратный способ, которым я мог бы достичь этого. Кто-нибудь может предложить какие-либо дальнейшие указания, пожалуйста?
Спасибо,
Trev