Цикл статей «Учебник Java 8».
Следующая статья — «Java 8 вложенные классы и лямбда-выражения».
Предыдущая статья — «Классы и объекты в Java 8».
Содержание
— Предопределённые аннотации из пакета java.lang
Введение
Аннотации представляют собой некую мета-информацию. Они не выполняют какого-либо действия сами по себе, но они могут предоставлять дополнительную информацию, которая может быть использована компилятором, различными утилитами сборки и генерации кода, а также они могут обрабатываться во время выполнения программы.
Аннотации предваряются знаком собачки. Пример часто используемой аннотации @Override, которая указывает компилятору, что этот метод переопределяет базовый метод:
1 2 3 4 |
@Override public void someMethod1() { // ... } |
Аннотации могут иметь элементы:
1 2 3 |
@SuppressWarnings(value = "unchecked") public void method1() { } |
Если элементов много, то они разделяются запятой, если элемент только один, и его имя value , то его название можно не указывать:
1 2 |
@SuppressWarnings("unchecked") void myMethod() { ... } |
Объявление аннотаций
Предположим, что вы по традиции при объявлении каждого нового класса монстра записываете в комментариях информацию об авторах в таком виде:
1 2 3 4 5 6 7 8 9 10 11 |
class Goblin { // author : John Clark // sprites : Izabella Simpson // sound : Michael Lermontov // code : Pushkin A. // createdAt : 2016-03-30 // description : Goblin is lurking creature. // comments : // ... code } |
Вы можете записывать эту информацию с помощью аннотаций. Для этого вам сперва нужно объявить эту аннотацию:
1 2 3 4 5 6 7 8 9 10 11 |
@interface Monstr { String author(); String sprites(); String sound(); String code(); String createdAt() default "0000-00-00"; String description(); // Example of array use String[] comments(); } |
Теперь можно применить его к нашему классу Goblin :
1 2 3 4 5 6 7 8 9 10 11 |
@Monstr( author="John Clark", sprites = "Izabella Simpson", sound = "Michael Lermontov", code = "Pushkin A.", createdAt = "2016-03-30", description = "Goblin is lurking creature", comments = {"lol", "gg", "Аффтар жжёт"} ) class Goblin { } |
Обратите внимание на запись элементов аннотации ( author , sprites , sound ) и на запись массива элементов с использованием фигурных скобок ( comments ).
Можно использовать предопределённую аннотацию @Documented, чтобы наша аннотация попадала в документацию, сгенерированную утилитой JavaDoc:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import java.lang.annotation.Documented; @Documented @interface Monstr { String author(); String sprites(); String sound(); String code(); String createdAt() default "0000-00-00"; String description(); // Example of array use String[] comments(); } |
Предопределённые аннотации
Предопределённые аннотации из пакета java.lang
@Deprecated указывает, что элемент устарел и не должен использоваться. Компилятор Java генерирует предупреждение, если вы используете класс, метод или поле, помеченные аннотацией @Deprecated. Устаревший элемент должен быть также помечен тегом JavaDoc @deprecated :
1 2 3 4 5 6 |
/** * @deprecated * explanation of why it was deprecated */ @Deprecated static void deprecatedMethod() { } |
@Override указывает, что метод переопределяет метод базового класса. Эту аннотацию использовать не обязательно, но рекомендуется.
1 2 3 4 |
@Override public int myMethod1(double x) { // ... } |
Если метод с @Override не может корректно переопределить метод базового класса, то компилятор генерирует ошибку.
@SuppressWarnings подавляет предупреждения. Пример подавления предупреждения об устаревшем методе:
1 2 3 4 5 6 7 8 |
// Указываем компиляторе не генерировать // предупреждение о использовании // устаревшего метода. @SuppressWarnings("deprecation") void useDeprecatedMethod() { // Используем устаревший метод. objectOne.deprecatedMethod(); } |
Каждое предупреждение принадлежит какой-либо категории. В спецификации Java описано две категории. В @SupressWarnings можно указывать несколько категорий:
1 |
@SuppressWarnings({"unchecked", "deprecation"}) |
Различные реализации компиляторов и различные IDE могут добавлять свои категории предупреждений. Неподдерживаемые названия категорий пропускаются при использовании @SuppressWarnings.
@SafeVarargs применяется к методу или конструктору и указывает, что код не осуществляет потенциально опасных операций со своим varargs-параметром (параметр, принимающий произвольное число параметров).
@FunctionalInterface указывает, что это объявление типа будет функциональным интерфейсом Java 8.
Мета-аннотации
Аннотации, применяемые к другим аннотациям, называются мета-аннотациями. Есть несколько мета-аннотаций в пакете java.lang.annotation :
@Retention определяет, как аннотация будет сохранена:
- RetentionPolicy.SOURCE — аннотация будет только в исходном коде, и она будет игнорироваться компилятором.
- RetentionPolicy.CLASS — аннотация будет доступна компилятору, но но будет игнорироваться виртуальной машиной Java.
- RetentionPolicy.RUNTIME — аннотация будет сохраняться JVM и будет доступна во время выполнения.
@Documented — указывает, что элементы, помеченные этой аннотацией, должны документироваться JavaDoc. По умолчанию аннотации не включаются в документацию.
@Target — указывает какие элементы можно помечать этой аннотацией:
- ElementType.ANNOTATION_TYPE — данная аннотация может быть применена к другой аннотации.
- ElementType.CONSTRUCTOR — может быть применена к конструктору.
- ElementType.FIELD — может быть применена к полю.
- ElementType.LOCAL_VARIABLE — может быть применена к локальной переменной.
- ElementType.METHOD — может быть применена к методу.
- ElementType.PACKAGE — может быть применена к пакету.
- ElementType.PARAMETER — может быть применена к параметрам метода.
- ElementType.TYPE — может быть применена классу, интерфейсу, аннотации или перечислению.
@Inherited — аннотация может быть унаследована от базового класса (по умолчанию не наследуются). Когда запрашивается аннотация класса, и у класса нет такой аннотации, то запрашивается аннотация базового класса. Эта аннотация может быть применена только к классам.
@Repeatable — аннотация может быть применена несколько раз.
Допустим мы хотим применить аннотацию @Author несколько раз для указания нескольких авторов:
1 2 3 4 5 |
@Author("Petya") @Author("Vasya") @Author("Suslik") class Goblin { } |
Тогда мы должны объявить такую аннотацию вот так:
1 2 3 4 5 6 |
import java.lang.annotation.Repeatable; @Repeatable(Authors.class) @interface Author { String value(); } |
Обратите внимание, что добавлена аннотация @Repeatable с указанием Authors.class , который мы должны объявить как аннотацию с массивом аннотация Author:
1 2 3 |
@interface Authors{ Author[] value(); } |
Теперь мы можем указывать аннотацию @Author столько раз, сколько захотим, для любого класса.
Цикл статей «Учебник Java 8».
Следующая статья — «Java 8 вложенные классы и лямбда-выражения».
Предыдущая статья — «Классы и объекты в Java 8».
Если я правильно понял, бесполезная вещь для начинающего разработчика-одиночки.
Народ на стороннем форуме писал, что из аннотаций полезна лишь @Override.
Ну на начальном этапе да, только @Override пригодиться. Потом, когда до Spring и Hibernate дойдёте, вот там они сильно используются.
Спасибо за полезные ответы на комментарии.
Спасибо за хорошую статью!
«@Retention определяет, как аннотация будет сохранена:»
И как она будет сохранена? Полностью, Слева на право, В аски коде, зашифровано или другим способом?