Генерация геттеров / сеттеров в Java (снова) - PullRequest
3 голосов
/ 13 июля 2010

Я рассматриваю подходы для написания


class MyClass {
  @Get
  @Set
  protected int aValue;
}

, а затем автоматически сгенерирую методы get_aValue () и set_AValue () для класса.

Я нашел эти возможности:

1a) Во время компиляции.Используйте процессор аннотаций для отдельной обработки MyClass.java, затем напишите новый MyClass.java и, наконец, используйте этот последний (заменив оригинал) с остальной частью .java

1b) Во время компиляции.Используйте процессор аннотаций для генерации файла MyClassGenerated.java с новым классом (с методами get / set), который является подклассом исходного MyClass.

2) Во время выполнения.Используйте java.lang.instrument и внешний инструмент (например, BCEL) для создания нового кода в MyClass.class.

Что ж, вопросы таковы: учитывая, насколько это возможно, я не хочуиспользовать сторонние библиотеки (например, проект lombok или BCEL)

a) Я пропускаю какой-либо другой подход?

b) Какой подход вы бы использовали?

Полагаю, я буду использовать 1a), поскольку

1b) не является чистым (остальная часть программы должна использовать MyClassGeneradted вместо исходного MyClass, хотя, возможно, это только вопросимена)

2) действительно сложно (по крайней мере для меня).

Ответы [ 6 ]

5 голосов
/ 13 июля 2010

Это звучит как большая работа только для генерации методов получения и установки. Почему бы просто не использовать генератор затмений и генератор сеттеров :

generate getters and setters screenshot

4 голосов
/ 13 июля 2010

Вам не хватает чего-то, что, я бы сказал, является лучшим подходом, если вы хотите пойти по этому пути:

1c) Во время компиляции.Скомпилируйте класс как обычно, затем используйте процессор аннотаций APT, чтобы изменить файл .class (не исходный файл), чтобы добавить соответствующие методы get и set в байт-код.

Таким образомВаш источник остается нетронутым, вам не нужно возиться с временными файлами, и фактический скомпилированный класс точно такой, каким вы хотите его видеть.


Тем не менее, это использует кувалду, чтобы открытьорех.Это выполнимо, но теперь ваш код не является строго Java в том смысле, что если кто-то возьмёт его и запустит javac, он получит класс без методов получения и установки.Это затруднит отладку, так как все номера строк будут испорчены, и если вы не уверены, что сделали правильно с вашим процессором аннотаций, вы даже не сможете увидеть источник методов получения и установкиисправлять ошибки.Инструменты статического анализа сообщат вам, что атрибут никогда не используется и т. Д.

Я согласен с этим - просто сгенерируйте их в исходном файле, используя методы, которые предоставляет каждая IDE.Это занимает чуть больше времени, чем написание аннотаций, и это понимают все разработчики и инструменты.У Java нет свойств - преодолеть это.: -)

3 голосов
/ 27 апреля 2011

Project Lombok в значительной степени именно то, что вы хотите, хотя реализация отличается.

3 голосов
/ 13 июля 2010

Практически говоря, я обычно использую подход 3 - я просто кодирую поля и использую Eclipse IDE для автоматического создания методов получения и установки.(NetBeans и IntelliJ должны иметь схожие функции)

С помощью инструментов автоматической генерации среды IDE вы даже можете определить видимость сгенерированных методов получения / установки (вы можете захотеть ограничить видимость метода установки частными) или отредактировать шаблон, еслиВам нужен дополнительный код тела метода.

3 голосов
/ 13 июля 2010
  • a) Вы можете использовать язык JVM (совместимый с Java), который поддерживает это
  • b) Я написал бы его в Scala

Серьезно, если вы считаете,боль языка и не хотите использовать костыли, такие как ткачи байт-кода или внешние библиотеки, вы должны искать более зеленые пастбища.

1 голос
/ 14 июля 2010

Я не знаю, почему не был предложен другой очевидный выбор, но я бы рассмотрел другой подход, где вы просто определяете интерфейсы и используете библиотеку, которая реализует указанные сеттеры, геттеры и необходимые внутренние поля.

Таким образом, вы бы указали что-то вроде

открытый интерфейс Bean { public int getX (); public void setX (int value); }

и попросить библиотеку создать экземпляр типа для этого (и, возможно, вспомогательные методы для создания экземпляров типа). При необходимости аннотации можно использовать для дальнейшей настройки, если это необходимо, но для be / style style bean это не так.

Это отличается от вашего (2), который не будет работать как есть, если я не пропущу что-то: дело в том, что у вас должны быть методы, доступные во время компиляции. И это то, что решит использование интерфейсов. Генерация кода будет необходима, но может быть автоматизирована.

Я ожидал бы, что такие библиотеки существуют, но если нет, то написание универсальной библиотеки должно быть вполне выполнимым с использованием библиотек для генерации байт-кода (asm, cglib, janino, javassist и т. Д.).

Написание такой библиотеки для простого варианта использования, конечно, тяжело, но использование одного из них, похоже, имеет смысл.

... и вполне возможно, что с помощью IDE будет проще всего решить конкретный случай, каким бы он ни был. : -)

...