Понимание аннотаций Java - Учебное пособие по Java @annotations
Опубликовано: 2019-10-22
Как и где используются аннотации в Java?
Аннотация на языке программирования Java — это особая форма синтаксических метаданных, которые можно добавлять в исходный код Java.
Классы, методы, переменные, параметры и пакеты могут быть аннотированы. В отличие от тегов Javadoc, аннотации Java могут быть отражающими, поскольку они могут быть встроены в файлы классов, созданные компилятором, и могут быть сохранены виртуальной машиной Java, чтобы их можно было извлечь во время выполнения.
Можно создавать мета-аннотации из существующих в Java, что делает эту концепцию более сложной.
Java определяет набор аннотаций, встроенных в язык.

Аннотации, применяемые к коду Java:
- @Override — проверяет, является ли функция переопределением. Вызывает предупреждение компиляции, если функция не найдена ни в одном из родительских классов.
- @Deprecated — помечает функцию как устаревшую. Вызывает предупреждение компиляции, если функция используется.
- @SuppressWarnings — указывает компилятору подавлять предупреждения времени компиляции, указанные в параметрах аннотации.
Аннотации, примененные к другим аннотациям:
- @Retention — указывает, как хранится помеченная аннотация — только в коде, скомпилированном в класс или доступном во время выполнения посредством отражения.
- @Documented — помечает другую аннотацию для включения в документацию.
- @Target — помечает другую аннотацию, чтобы ограничить, к каким java-элементам может быть применена аннотация.
- @Inherited — помечает другую аннотацию для наследования подклассам аннотированного класса (по умолчанию аннотации не наследуются подклассами).
Давайте взглянем на них на примере примеров:
1) @Override Аннотация:
Его наличие указывает компилятору, что аннотированный метод должен переопределить существующий метод суперкласса.
Наиболее распространенный вариант использования @Override — с методами объекта :
1 2 3 4 |
@ Override public int hashValue ( ) { System . out . Println ( "This method is using @Override Annotation" ) ; } |
Основная причина, по которой @Override была создана, заключалась в том, чтобы иметь дело с простыми типографскими ошибками .
Например, метод, ошибочно объявленный как
1 |
public int hashvalue ( ) { . . . } |
на самом деле не является переопределением — в имени метода все буквы нижнего регистра , поэтому оно не совсем совпадает с именем метода hashValue() . Однако он отлично скомпилируется. Такую ошибку легко сделать, но трудно поймать, что является опасной комбинацией. Использование аннотации @Override предотвращает такие ошибки.
У вас должна быть привычка использовать @Override всякий раз, когда вы переопределяете метод суперкласса.

2) @Устаревшая аннотация:
Эта аннотация указывает, что отмеченный элемент устарел и больше не должен использоваться. Компилятор генерирует предупреждение всякий раз, когда программа использует метод, класс или поле с аннотацией @Deprecated
.
Когда элемент устарел, его также следует задокументировать с помощью тега Javadoc @deprecated
, как показано в следующем примере.
1 2 3 4 |
< strong > @ Deprecated < / strong > static void deprecatedMethod ( ) { System . out . Println ( "This method is Deprecated.." ) ; } |
3) @SuppressWarnings Аннотация:
Просто скажите компилятору, пожалуйста, не кричите. Я знаю, что я делаю .
1 2 3 4 |
@ SuppressWarnings ( "serial" ) public class OldCode implements Serializable { System . out . Println ( "This is Old Code.." ) ; } |
4) Аннотация @Retention:
Аннотации хранения указывают, где и как долго должны храниться аннотации этого типа.
Есть три значения:
- RetentionPolicy.SOURCE — Аннотации этого типа будут сохраняться только на уровне исходного кода и будут игнорироваться компилятором.
- RetentionPolicy.CLASS — аннотации этого типа будут сохранены компилятором во время компиляции, но будут игнорироваться виртуальной машиной.
- RetentionPolicy.RUNTIME — аннотации этого типа будут сохранены виртуальной машиной, поэтому их можно будет прочитать только во время выполнения.
1 2 3 4 |
@ Retention ( RetentionPolicy . RUNTIME ) public @ interface Crunchify_Retention { String returnSomething ( ) ; } |
5) @Документированная аннотация:
1 2 3 4 |
@ Documented public @ interface Crunchify_Documented { String writeDocument ( ) ; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class DocumentedAnnotations { public static void main ( String arg [ ] ) { new DocumentedAnnotations ( ) . performRetention ( ) ; new DocumentedAnnotations ( ) . performDocumented ( ) ; } @ Crunchify_Retention ( returnSomething = "Hello retention test" ) public void performRetention ( ) { System . out . printf ( "Testing annotation 'Crunchify_Retention'" ) ; } @ Crunchify_Documented ( writeDocument = "Hello document" ) public void performDocumented ( ) { System . out . printf ( "Testing annotation 'Crunchify_Documented'" ) ; } } |
Теперь попробуйте запустить команду Java Doc и посмотрите вывод.

6) Аннотация @Target:
Цель указывает, какие элементы программы могут быть аннотированы с использованием экземпляров аннотированного типа аннотации. Значение Target является одним из членов перечисления java.lang.annotation.ElementType
:
- АННОТАЦИЯ_ТИП. Аннотированный тип аннотации можно использовать для аннотирования объявления типа аннотации.
- КОНСТРУКТОР. Аннотированный тип аннотации можно использовать для аннотирования объявления конструктора.
- ПОЛЕ. Аннотированный тип аннотации можно использовать для аннотирования объявления поля.
- ЛОКАЛЬНАЯ_ПЕРЕМЕННАЯ. Аннотированный тип аннотации можно использовать для аннотирования объявления локальной переменной.
- МЕТОД. Аннотированный тип аннотации можно использовать для аннотирования объявления метода.
- УПАКОВКА. Аннотированный тип аннотации можно использовать для аннотирования объявлений пакетов.
- ПАРАМЕТР. Аннотированный тип аннотации можно использовать для аннотирования объявлений параметров.
- ТИП. Аннотированный тип аннотации можно использовать для аннотирования объявлений типа.
1 2 3 4 |
@ Target ( value = METHOD ) You can have multiple values in the Target annotation . @ Target ( value = { TYPE , FIELD , METHOD , PARAMETER , CONSTRUCTOR , LOCAL_VARIABLE } ) |
7) @Унаследованная аннотация:
Точно так же, как звучит название, тип аннотации @Inherited
наследуется подклассами аннотированного типа.
1 2 3 4 5 6 7 8 9 10 |
@ Inherited @ interface ForEveryone { } @ interface JustForMe { } @ ForEveryone @ JustForMe class Superclass { } class Subclass extends Superclass { } |
В этом примере Superclass
был явно аннотирован как @ForEveryone
так и @JustForMe
. Subclass
не был явно отмечен ни одним из них; однако он наследует @ForEveryone
, потому что последний @Inherited
.
@JustForMe
не аннотируется, поэтому он не наследуется Subclass
.
Вот аннотации уровня класса
