Force Uniform Значения конструктора и аннотации метода? - PullRequest
0 голосов
/ 03 марта 2020

Я пишу пользовательский API, используя Reflection для сохранения объектов в файл. У меня следующая структура классов:

@Constructor
public XYZPOJO(@Key(key = "word") String word, @Key(key = "variations") ArrayList<String> varList) {
    this.word = word;
    this.varList = varList;
}


String word;
ArrayList<String> varList = new ArrayList<String>();


@Key(key = "word")
public String getWord() {
    return word;
}

@Key(key = "variations")
public ArrayList<String> getVarList() {
    return varList;
}

При сохранении объекта в файл моя программа извлекает каждый метод, помеченный @Key, вызывает метод и сохраняет вызванное значение в файл, используя значение @Key в качестве Имя свойства. Позже, когда я захочу создать экземпляр Object, он будет искать конструктор, отмеченный @Constructor, а затем извлечет значение @Key каждого параметра в конструкторе и получит значение ключа (свойства) из файла.

Моя основная проблема заключается в том, что для каждого поля, которое я хочу сохранить, мне нужно продублировать аннотацию @Key (и значение) перед каждым методом и перед соответствующим параметром в конструкторе. Более того, если обе аннотации конструктора / метода не совпадают точно, это не приведет к созданию экземпляра Object. Очень легко случайно скопировать неправильные значения.

Есть ли способ определить каждый @Key только один раз?

Я думал добавить @Key только один раз перед каждым полем I wi sh для сохранения, однако я верю (пожалуйста, исправьте меня, если я ошибаюсь), что я больше не смогу создавать экземпляр класса с помощью конструктора (я считаю, что мне нужно было бы создать экземпляр класса путем непосредственной установки значения каждого поля с помощью отражения, тем самым обходя конструктор, правильно?). Однако это не идеально, так как конструктор выполняет определенные необходимые функции до создания экземпляра класса.

Какие еще существуют решения?

Спасибо!

1 Ответ

1 голос
/ 03 марта 2020

Вы можете сделать это, как любая другая библиотека для сериализации (или просто переключиться на одну из этих библиотек, так как они все поддерживают все, что вы делаете), так что возможные решения:

  1. Пропустить аннотацию по умолчанию, просто используйте имя получателя (например, getMoney -> money) и используйте аннотацию только в конструкторе. И на геттер, если вы хотите использовать другое имя в сериализованной форме. Кроме того, вы можете найти поле с тем же именем, чтобы проверить аннотации на нем, но это необязательно и не нужно.

  2. Аннотируйте только параметры в конструкторе, но позволяйте задавать как имя, так и имя свойства (по умолчанию вы можете предполагать, что свойство name ==, если кто-то не предоставил оба значения), а позже вы можете изменить его на Имя метода-получателя, например money -> getMoney (просто добавьте get и введите первую букву в верхнем регистре)

  3. Примените первую идею, но также используйте имена параметров из конструктора, который доступны во время выполнения, если кто-то компилирует код с флагом -parameters. И тогда вам не нужны никакие аннотации, если вы не хотите использовать другое имя в сериализованной форме, а затем просто добавьте аннотацию только к полю / получателю.

Примечание: Типичные библиотеки просто сканируют publi c методы поиска свойств. Поэтому они ищут методы, которые начинаются с get или is, за которыми следует заглавная буква, которые не имеют аргументов и некоторого возвращаемого типа. Как типичный класс данных будет выглядеть так.

...