Аннотации были добавлены в Java 5 для предоставления метаданных, которые может использовать компилятор и различные фреймворки. Изначально они помогали инструментам (например, JUnit или Hibernate) лучше взаимодействовать с кодом без необходимости писать повторяющийся или внешний конфиг.
Аннотации позволяют добавлять информацию к классам, методам, полям, параметрам и даже локальным переменным. На этапе компиляции, рантайма или во время обработки исходного кода они могут быть использованы для валидации, генерации дополнительных файлов, или изменения поведения программы.
Для объявления своей аннотации используется ключевое слово @interface.
Пример кода:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyAnnotation { String value(); } class Example { @MyAnnotation("Test") public void annotatedMethod() {} }
Ключевые особенности:
Аннотации влияют только на рантайм?
Нет, аннотации могут быть ограничены только исходным кодом (SOURCE), байткодом (CLASS) или быть доступны на этапе выполнения (RUNTIME). Их влияние зависит от RetentionPolicy.
@Retention(RetentionPolicy.SOURCE) public @interface SourceOnly {}
Могут ли параметры аннотации быть любого типа?
Нет, допустимые типы — только примитивы, строки, перечисления, другие аннотации и массивы этих типов. Объекты нельзя использовать.
Можно ли наследовать аннотации?
Строго говоря, аннотации не наследуются как классы. Исключением является аннотация с @Inherited, которая распространяется только на классы-наследники (никак не затрагивая методы).
Разработчик в большом проекте создал десятки разных аннотаций для автоматизации тестирования, не удосужившись их прописать, документировать и ограничить область действия. В результате новому члену команды было сложно понять, какие аннотации где работают.
Плюсы:
Минусы:
В команде внедрили строгую стратегию для написания своих аннотаций: добавляли только необходимые, подробно описывали каждую, и ограничивали их область действия.
Плюсы:
Минусы: