Статьи

Учебник по аннотациям Java с пользовательскими аннотациями

Аннотации Java предоставляют информацию о коде, и они не имеют прямого влияния на код, который они комментируют. В этом руководстве мы узнаем об аннотациях Java, о том, как писать собственные аннотации , об использовании аннотаций и о том, как анализировать аннотации с помощью отражения.

Аннотации введены в Java 1.5, и теперь они активно используются в таких средах Java, как Hibernate, Jersey , Spring. Аннотация — это метаданные о программе, встроенные в саму программу. Это может быть проанализировано инструментом анализа аннотации или компилятором. Мы также можем указать доступность аннотации либо только во время компиляции, либо до времени выполнения.

До аннотаций метаданные программы были доступны через комментарии java или javadoc, но аннотации предлагают нечто большее. Он не только содержит метаданные, но и делает его доступным для среды выполнения, а анализаторы аннотаций могут использовать его для определения потока процесса. Например, в веб-службе Джерси мы добавляем аннотацию PATH со строкой URI к методу, а во время выполнения джерси анализирует ее, чтобы определить метод, который нужно вызвать для данного шаблона URI.

Создание пользовательских аннотаций в Java

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
package com.journaldev.annotations;
 
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInfo{
    String author() default 'Pankaj';
    String date();
    int revision() default 1;
    String comments();
}
  • Методы аннотации не могут иметь параметров.
  • Методы аннотации возвращаемые типы ограничены примитивами, String, Enums, Annotation или их массив.
  • Методы аннотации могут иметь значения по умолчанию.
  • К аннотациям могут быть прикреплены метааннотации. Мета аннотации используются для предоставления информации о аннотации. Существует четыре типа метааннотаций:
    1. @Documented — указывает, что элементы, использующие эту аннотацию, должны быть задокументированы javadoc и подобными инструментами. Этот тип должен использоваться для аннотирования объявлений типов, аннотации которых влияют на использование аннотированных элементов их клиентами. Если объявление типа аннотируется с помощью Documented, его аннотации становятся частью общедоступного API аннотированных элементов.
    2. @Target — указывает типы элементов программы, к которым применяется тип аннотации. Возможные значения: TYPE, METHOD, CONSTRUCTOR, FIELD и т. Д. Если мета-аннотация Target отсутствует, аннотацию можно использовать для любого элемента программы.
    3. @Inherited — указывает, что тип аннотации автоматически наследуется. Если пользователь запрашивает тип аннотации в объявлении класса, а объявление класса не имеет аннотации для этого типа, то суперкласс класса будет автоматически запрашиваться для типа аннотации. Этот процесс будет повторяться до тех пор, пока не будет найдена аннотация для этого типа или пока не будет достигнута вершина иерархии классов (Object).
    4. @Retention — указывает, как долго аннотации с аннотированным типом должны храниться. Он принимает аргумент RetentionPolicy, возможные значения которого: SOURCE, CLASS и RUNTIME

Java встроенные аннотации

Java Предоставляет три встроенные аннотации.

  1. @Override — Когда мы хотим переопределить метод Superclass, мы должны использовать эту аннотацию, чтобы сообщить компилятору, что мы переопределяем метод. Поэтому, когда метод суперкласса будет удален или изменен, компилятор покажет сообщение об ошибке.
  2. @Deprecated — когда мы хотим, чтобы компилятор знал, что метод устарел, мы должны использовать эту аннотацию. Java рекомендует, чтобы в javadoc мы предоставили информацию, почему этот метод устарел и какую альтернативу использовать.
  3. @SuppressWarnings — это просто сказать компилятору игнорировать определенные предупреждения, которые они генерируют, например, используя необработанные типы в обобщениях. Это политика хранения SOURCE, и она отбрасывается компилятором.

Давайте посмотрим на пример Java, показывающий использование встроенных аннотаций, а также использование пользовательских аннотаций, созданных нами в приведенном выше примере.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.journaldev.annotations;
 
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
 
public class AnnotationExample {
 
    public static void main(String[] args) {
    }
 
    @Override
    @MethodInfo(author = 'Pankaj', comments = 'Main method', date = 'Nov 17 2012', revision = 1)
    public String toString() {
        return 'Overriden toString method';
    }
 
    @Deprecated
    @MethodInfo(comments = 'deprecated method', date = 'Nov 17 2012')
    public static void oldMethod() {
        System.out.println('old method, don't use it.');
    }
 
    @SuppressWarnings({ 'unchecked', 'deprecation' })
    @MethodInfo(author = 'Pankaj', comments = 'Main method', date = 'Nov 17 2012', revision = 10)
    public static void genericsTest() throws FileNotFoundException {
        List l = new ArrayList();
        l.add('abc');
        oldMethod();
    }
 
}

Я считаю, что пример не требует пояснений и показывает использование аннотаций в разных случаях.

Разбор аннотаций Java

Мы будем использовать Reflection для анализа аннотаций Java из класса. Обратите внимание, что политика хранения аннотаций должна быть RUNTIME, иначе ее информация не будет доступна во время выполнения, и мы не сможем извлечь из нее какие-либо данные.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.journaldev.annotations;
 
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
 
public class AnnotationParsing {
 
    public static void main(String[] args) {
        try {
            for (Method method : AnnotationParsing.class
                    .getClassLoader()
                    .loadClass(('com.journaldev.annotations.AnnotationExample'))
                    .getMethods()) {
                // checks if MethodInfo annotation is present for the method
                if (method
                        .isAnnotationPresent(com.journaldev.annotations.MethodInfo.class)) {
                    try {
                        // iterates all the annotations available in the method
                        for (Annotation anno : method.getDeclaredAnnotations()) {
                            System.out.println('Annotation in Method ''
                                    + method + '' : ' + anno);
                        }
                        MethodInfo methodAnno = method
                                .getAnnotation(MethodInfo.class);
                        if (methodAnno.revision() == 1) {
                            System.out.println('Method with revision no 1 = '
                                    + method);
                        }
 
                    } catch (Throwable ex) {
                        ex.printStackTrace();
                    }
                }
            }
        } catch (SecurityException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
 
}

Вывод вышеуказанной программы:

1
2
3
4
5
6
Annotation in Method 'public java.lang.String com.journaldev.annotations.AnnotationExample.toString()' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=1, comments=Main method, date=Nov 17 2012)
Method with revision no 1 = public java.lang.String com.journaldev.annotations.AnnotationExample.toString()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.oldMethod()' : @java.lang.Deprecated()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.oldMethod()' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=1, comments=deprecated method, date=Nov 17 2012)
Method with revision no 1 = public static void com.journaldev.annotations.AnnotationExample.oldMethod()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.genericsTest() throws java.io.FileNotFoundException' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=10, comments=Main method, date=Nov 17 2012)

Это все для учебника по Java-аннотациям, надеюсь, вы чему-то научились.

Ссылка: Учебное руководство по аннотациям Java с примером пользовательских аннотаций и синтаксический анализ с использованием Reflection от нашего партнера JCG Панкаджа Кумара в блоге Developer Recipes .