2016-04-12 11 views
1

Если я создаю пользовательскую аннотацию (например: @SaveFuncName("saveMe") добавит метод с именем saveMe() с кодом, который генерирует мой процессор), может ли компилятор javac использовать мой обработчик аннотации для добавления метода в класс? Или я могу создать только другой класс?Могу ли я добавить метод к классу из аннотации времени компиляции?

+0

Нет, это невозможно. Если вы изучите внутренний Javac API, можно напрямую изменить дерево синтаксиса, но это не для слабонервных. Немного связано: http://stackoverflow.com/questions/13690272/code-replacement-with-an-annotation-processor. Самое простое - создать суперкласс, например. 'saveMe()' и расширьте его. – Radiodef

+1

@Radiodef Спасибо. Можете ли вы опубликовать это как ответ, и я отметю, что он ответил. –

ответ

2

Или я могу создать только другой класс?

Это правильно. Существующий API не позволяет нам изменять существующие классы, просто генерировать новые.

С технической точки зрения, если вы хотите сделать некоторые хакерские вещи, можно использовать внутренний Javac API для изменения абстрактного дерева синтаксиса напрямую, но это не для слабонервных. Например, такой объект, как TypeElement, на самом деле является символом непосредственно из Javac, скрытым от нас интерфейсом. Дерево синтаксиса также доступно в режиме только для чтения через compiler tree API. Мы можем отбросить интерфейсы и изменить код таким образом. Так, например, Project Lombok работ.

(Но я не могу рекомендовать это делать. Я в основном объяснить это, потому что Ломбок является вещь, которая существует, так это выглядит как изменение классов возможно.)

Самые простые решения, чтобы сделать что-то вроде генерировать суперкласс, например saveMe() и продлить его или сгенерировать класс утилиты и делегировать ему. (Также предлагается here.)

+0

Так как Oracle представляет Lombok в мае 2017 года в «Журнале Java» ... означает ли это, что они выступают за хакерские вещи или считают, что APT может изменить текущий файл? Этот вопрос привел меня сюда, читая статью, потому что Ломбок, похоже, сделал именно это. Но я думаю, что нет никакого изящного способа построить это в APT API, и вам все равно нужно будет отредактировать AST. – Stroboskop

+0

@Stroboskop Это хаки, потому что это недокументировано, поэтому вам нужно прочитать исходный код javac, чтобы выяснить, как работает материал. Может быть, автор этой статьи просто не знает, что Ломбок делает за кулисами. У Ломбока есть своя реклама, если вы хотите увидеть, что они говорят: http://jnb.ociweb.com/jnb/jnbJan2010.html#controversy Лично я надеюсь, что модификация AST или, по крайней мере, просто добавление методов, добавляется как но я сомневаюсь, что это произойдет в ближайшее время. – Radiodef