Аннотациями(annotations) называются дескрипторы, которые разработчики вставляют в свой исходный код для того, чтобы та или иная утилита могла обрабатывать их. Эти утилиты могут работать как на уровне исходного кода, так и на уровне файлов классов, в которые компилятор помещает аннотации.
Аннотации не влияют на способ компиляции программ. Компилятор Java генерирует одинаковые инструкции виртуальной машины как с, так и без аннотаций.
Для извлечения пользы из аннотаций необходимо выбирать средство обработки (processing tool). В код вставляются аннотации, понятные определенному средству обработки, которое потом всегда и применяется для их расшифровки.У аннотаций существует масса сфер применения, и такая их универсальность сначала может вызывать путаницу. Ниже перечислены некоторые из этих сфер:
- автоматическая генерация вспомогательных файлов, вроде файлов дескрипторов развертывания или классов информации о bean-компонентах;
- автоматическая генерация кода для тестирования, регистрации, семантической обработки транзакций и так далее.
Мы начнем обсуждение аннотаций с базовых концепций и продемонстрируем их применение на практике с помощью конкретного примера: в частности, мы пометим методы как слушатели событий для компонентов AWT и покажем обработчик аннотаций, анализирующий аннотации и подключающий слушателей.
Далее мы подробно рассмотрим синтаксические правила. И, наконец, напоследок мы предложим два более сложных примера обработки аннотаций: первый с обработкой аннотаций на уровне исходного кода, а второй с обработкой аннотаций на уровне файлов классов за счет использования технологии Apache Bytecode Engineering Library и вставки в аннотированные методы дополнительных байт-кодов.
Ниже приведен пример простой аннотации:
1 2 3 4 5 |
public class MyClass { ... @Test public void checkRandomInsertions() } |
Аннотация @Test аннотирует метод checkRandomInsertions.
В Java аннотация применяется подобно модификатору(modifier) и помещается перед аннотируемым элементом без точки с запятой. Напомним, модификатор это ключевое слово вроде public или static. Перед именем каждой аннотации ставится символ @, подобно тому, как это делается в случае комментариев Javadoc. Однако комментарии Javadoc размещаются внутри разделителей /**…*/, тогда как аннотации являются частью кода.
Сама по себе аннотация @Test ничего не делает. Для того чтобы приносить пользу, ей необходим инструмент. Например, инструмент тестирования JUnit 4 (доступный на сайте http://junit.org) умеет вызвать все помеченные аннотацией @Test методы при тестировании класса. Другой инструмент может удалять все тестовые методы из файла класса, так чтобы они не поставлялись с программой уже после прохождения ею тестирования.
Аннотации могут определяться с элементами, например:
1 |
@Test(timeout="10000") |
Эти элементы могут обрабатываться инструментами, читающими аннотации. Элементы могут выглядеть и по-другому. Более подробно о них будет рассказываться в следующих статьях.
Помимо методов снабжаться аннотациями также могут классы, поля и локальные переменные — аннотация может размещаться во всех тех же местах, что модификатор вроде public или static.
Каждая аннотация должна определяться с помощью аннотационного интерфейса(annotation interface). Методы этого интерфейса должны соответствовать элементам определяемой им аннотации. Например, JUnit-аннотация Test определяется с помощью такого интерфейса:
1 2 3 4 5 6 7 |
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Test { long timeout() default 0L; ... } |
Объявление @interface создает фактический интерфейс Java, а обрабатывающие аннотации инструменты получают объекты, которые реализуют уже аннотационный интерфейс. Для извлечения элемента timeout конкретно аннотации Test, например, инструмент будет вызывать метод timeout.
Аннотации Target и Retention являются мета-аннотациями(meta-annotations). Они аннотируют аннотацию Target, помечая ее как аннотацию, которая может применяться только к методам и которая должна сохраняться при загрузке файла класса в виртуальную машину. Более подробно о них будет рассказываться в следующих моих статьях.