Аннотации, часть 1: обзор Аннотации - дополнительная информац | Java: fill the gaps
Аннотации, часть 1: обзор
Аннотации - дополнительная информация к исходному коду. @Override, @Deprecated, @SuppressWarnings - вот это всё.
Первая часть будет о том, как сделать свою аннотацию, а во второй расскажу, когда и зачем это нужно.
Создать аннотацию легко:
public @interface MyAnnotation {}
Почему ключевое слово @интерфейс, а не @аннотейшн?
Во времена java 4 аннотаций не было и для дополнительной информации классу добавляли интерфейс-маркер. В интерфейсах Cloneable, Serializable, Remote нет методов, они используются только как дополнительный признак класса.
Подход рабочий, но похож на костыль. Цель интерфейса - показать контракт класса, поэтому для маркировки кода в java 5 ввели аннотации.
Вернёмся в наши дни. Посмотрим исходный код @Deprecated:
@Retention(RUNTIME)
@Target(value={FIELD,…})
public @interface Deprecated {
String since() default "";
boolean forRemoval() default false;
}
На этом примере видно, из чего состоит аннотация:
Поля
Содержат доп. информацию. Если указать значение по умолчанию, поле становится необязательным:
@Deprecated(since="14")
// forRemoval по умолчанию false
Список внутри @Target показывает элементы, для которых работает аннотация.
В java 7 аннотации доступны для классов, методов, параметров, полей и переменных.
В java 8 аннотации действуют везде, где указан тип. Можно писать даже такое:
new @Test Account()
throws @Test IOException
implements @Test Comparable<@Test T>
Такие аннотации называются type annotations и используются в IDE и компиляторах для анализа и строгого контроля типов.
Аннотации нельзя ставить для имён переменных. Правильный ответ на вопрос перед постом - ошибка в 5 строке:
@Test String doubled
String @Test out
@Retention определяет, когда доступна аннотация и как её можно использовать. Все виды подробно рассмотрим во второй части.
@Target и @Retention- это мета аннотации, то есть аннотации для аннотаций.
Какие ещё бывают мета-аннотации:
@Documented - аннотация появится в JavaDoc
@Inherited - наследуется подклассами
@Repeatable (Java 8) - можно использовать несколько раз для одного элемента. Иногда такое приятнее читать, чем один массив:
@Schedule(dayOfMonth="last")
@Schedule(dayOfWeek="Fri", hour="23")
Создать аннотацию легко, правильно применить - уже сложнее. С этим вопросом разберёмся во второй части.