JavaRush /Курсы /Модуль 2. Java Core /Параметры аннотаций

Параметры аннотаций

Модуль 2. Java Core
18 уровень , 2 лекция
Открыта

Главная польза от механизма аннотаций — не в использовании уже готовых стандартных аннотаций в JDK. Но и нужда в создании собственной аннотации появляется нечасто. Например, если мы разрабатываем большую систему или выделяем отдельную библиотеку, то на архитектурном уровне реализация собственной аннотации точно принесет плоды.

Давай попробуем создать аннотацию.

Для этого создаем файл, и вместо class или interface пишем @interface. Это и будет файл нашей аннотации. По внутренней структуре аннотация схожа с интерфейсом.


public @interface Sum {
   int sum() default 0;
}

@interface указывает на то, что это аннотация,
default сообщает, что параметр по умолчанию будет возвращать определённое значение.

Мы создали аннотацию и теоретически уже можем ее использовать, но сначала лучше заняться ее конфигурированием.

Дело в том, что без конфигурирования наша аннотация может быть применена к чему угодно (к классам, методам, атрибутам и т. д.), а поэтому использовать ее особо смысла нет. Как бы это странно не выглядело, нашу аннотацию нужно зааннотировать другими аннотациями!

Начнем с @Target.

Аннотация @Target (актуальна с Java 1.5) ограничивает возможность применения конфигурируемой аннотации. Для ограничения до определенного уровня в аннотацию @Target мы должны передать параметр, указывающий, для каких видов она может быть применена. Вот некоторые из часто используемых видов:

@Target(ElementType.PACKAGE) для пакетов
@Target(ElementType.TYPE) для классов
@Target(ElementType.CONSTRUCTOR) для конструкторов
@Target(ElementType.METHOD) для методов
@Target(ElementType.FIELD) для атрибутов (переменных) класса
@Target(ElementType.PARAMATER) для параметров метода
@Target(ElementType.LOCAL_VARIABLE) для локальных переменных

Если нужна аннотация с несколькими типами, то можно передать несколько параметров в виде массива:


@Target({ ElementType.PARAMETER, ElementType.LOCAL_VARIABLE })

Следующий важный элемент конфигурации — аннотация @Retention.

Эта аннотация укажет, в каком жизненном цикле кода наша аннотация будет доступна:

RetentionPolicy.SOURCE Аннотации, аннотированные с помощью политики хранения SOURCE, отбрасываются во время выполнения.
RetentionPolicy.CLASS Аннотации, аннотированные с помощью политики хранения CLASS, записываются в файл .class, но удаляются во время выполнения.
RetentionPolicy.RUNTIME Аннотации, аннотированные с помощью политики хранения RUNTIME, сохраняются во время выполнения и могут быть доступны в нашей программе во время выполнения.

Также для конфигурации можно использовать еще несколько аннотаций:

Аннотация Значение
@Inherited Позволяет классу-наследнику реализовать наследование аннотаций родительского класса.
@Documented Аннотация будет помещена в сгенерированную документацию javadoc.

Вот теперь давай попробуем создать собственную аннотацию.

Создадим аннотацию, которая будет аннотировать классы и методы и содержать информацию об авторе и версии написанного кода:


    @Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Info {
   String author() default "Author";
   String version() default "0.0";
}

Нашу аннотацию мы можем применять к методам и классам. Метаданные нашей аннотации будут доступны на этапе выполнения программы. Обрати внимание на параметры нашей аннотации. Мы можем вложить два параметра: имя и версию, но можем не класть, и тогда по умолчанию будут значения, которые мы указали (default "Author" и default "0.0").

Стоит отметить, что мы можем и не указывать дефолтное значение для параметров. В таком случае указание этого параметра становится обязательным.

При передаче параметров также обязательно указать параметр, который мы передаем через value = "value". Явное указание обязательно всегда, даже если параметр у аннотации единственный.

Применяем нашу аннотацию к нескольким классам:


@Info
public class MyClass1 {
   @Info
   public void myClassMethod() {}
}
 
@Info(version = "2.0")
public class MyClass2 {
   @Info(author = "Anonymous")
   public void myClassMethod() {}
}
 
@Info(author = "Anonymous", version = "2.0")
public class MyClass3 {
   @Info(author = "Anonymous", version = "4.0")
   public void myClassMethod() {}
}
Комментарии (9)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Равиль Хакимов Уровень 80
1 июля 2025
"Главная польза от механизма аннотаций — не в использовании уже готовых стандартных аннотаций в JDK. Но и нужда в создании собственной аннотации появляется нечасто." Я переведу: "Главная польза от механизма аннотаций — в использовании собственной аннотации, но нужда в создании собственной аннотации появляется нечасто."
25 октября 2025
Почему это не исправляется, ведь это не так сложно? А за перевод😁 спасибо.
Семён Уровень 68
4 мая 2025
"Главная польза от механизма аннотаций — не в использовании уже готовых стандартных аннотаций в JDK. Но и нужда в создании собственной аннотации появляется нечасто. "
Олег Уровень 111 Expert
27 мая 2023
Что пишут о некоторой пользе механизма аннотаций: 1. Добавляют доп. информацию (метаданные) к классам, методам, полям и другим элементам кода. Эта информация может быть использована для описания, настройки или инструкций по использованию кода. Например, аннотация может указывать автора, версию, правила использования, параметры конфигурации и многое другое. 2. Позволяют расширить возможности языка Java и добавить новые семантические слои. Например, аннотация @Override указывает компилятору, что метод переопределяет метод из суперкласса, что помогает обнаруживать ошибки во время компиляции. Аннотации также могут использоваться для создания собственных доменно-специфических языков (DSL) или аспектно-ориентированного программирования (AOP). 3. Инструменты статического анализа и проверки могут использовать аннотации для обнаружения ошибок, предупреждений или несоответствий в коде. Например, аннотации могут указывать правила форматирования, потенциально небезопасные операции, неиспользуемый код и другие проблемы, которые могут быть обнаружены и исправлены на ранней стадии разработки. 4. Аннотации могут быть использованы для генерации дополнительного кода во время компиляции. Инструменты и фреймворки могут обрабатывать аннотации и на их основе создавать или изменять код. Например, аннотации могут использоваться для генерации сериализаторов, десериализаторов, мапперов баз данных, маршаллеров XML и другого кода, который облегчает разработку и интеграцию. 5. Аннотации могут служить как дополнительная документация к коду, предоставляя информацию о его назначении, использовании или ограничениях. Аннотации могут быть обработаны для создания документации, автоматического тестирования или генерации пользовательского интерфейса. 6. Многие фреймворки и библиотеки используют аннотации для определения настроек, расширений или поведения. Аннотации позволяют разработчикам указывать требуемую конфигурацию или связь между компонентами, что упрощает разработку и интеграцию кода.
Роман Ильясович Уровень 46 Expert
27 декабря 2022
Не совсем понял: "При передаче параметров также обязательно указать параметр, который мы передаем через value = "value". Явное указание обязательно всегда, даже если параметр у аннотации единственный." Примера не увидел.
Олег Уровень 99 Expert
27 декабря 2022
Если хотите указать автором Иванова, а версию 2.0, то нужно написать: @Info(author = "Иванов ", version = "2.0") public class MyClass3 { ... } А вот так: @Info("Иванов", "2.0"), работать не должно. Я так понял, поправьте, если не прав. )
Anna Уровень 108 Expert
2 августа 2022
Эта фраза ужасна "Главная польза от механизма аннотаций — не в использовании уже готовых стандартных аннотаций в JDK. Но и нужда в создании собственной аннотации появляется нечасто. " Что автор хотел сказать и зачем так закрутил с "не"? Прочитала 3 раза и не поняла...Не говоря уже о плодах в следующем предложении...Какие плоды? Груши?
Марат Гарипов Уровень 108 Expert
17 августа 2022
:)
Руслан Никитин Уровень 109
1 октября 2024
судя по 108 уровню, Вы пожали свои плоды 😁