Аннотации Java
Аннотация — структурированные метаданные, привязанные к элементу программы. Сама по себе она ничего не выполняет: смысл придаёт компилятор, annotation processor, фреймворк или код через reflection.
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Required {
String message() default "value is required";
}
final class Command {
@Required
private String id;
}Мета-аннотации
| Аннотация | Назначение |
|---|---|
@Target | допустимые места применения |
@Retention | как долго хранится: SOURCE, CLASS, RUNTIME |
@Documented | включать в Javadoc |
@Inherited | наследовать аннотацию класса подклассом |
@Repeatable | разрешить несколько экземпляров |
@Inherited работает только при поиске аннотаций на классах: методы и интерфейсы через неё автоматически не наследуют метаданные.
Элемент аннотации может быть примитивом, String, Class, enum, другой аннотацией или массивом этих типов. Значение обязано быть compile-time допустимым; null использовать нельзя.
Два времени обработки
- compile time: генерация кода, проверка соглашений,
@Override; - runtime: контейнер читает
RUNTIME-аннотации и строит поведение, например маршрутизацию или транзакционный proxy.
boolean required = Command.class
.getDeclaredField("id")
.isAnnotationPresent(Required.class);Reflection на каждом запросе дорог и многословен, поэтому фреймворки обычно сканируют метаданные при старте и кэшируют результат.
Частые ошибки
- ожидать runtime-доступ от
RetentionPolicy.CLASS; - думать, что аннотация сама перехватит вызов метода;
- забывать
@Targetи разрешать бессмысленное применение; - прятать важную бизнес-логику за множеством неочевидных аннотаций.
На собеседовании
Что делает аннотация после добавления в код? Ничего без потребителя её метаданных.
Какая retention нужна для reflection? RUNTIME.
Работает ли @Inherited для методов? Нет.
Чем annotation processor отличается от reflection? Первый работает во время компиляции, второй исследует загруженные типы во время выполнения.
Связано: Понятие рефлективность Java, Класс Class, Аннотация Cacheable.