Annotation Analysis of Java

A person's life is like an article, it can only be continuously improved after many careful revisions.

 

Java annotation concept understanding:

  Java annotations, also known as Java annotations, are an annotation mechanism introduced by JDK5. The five familiar annotations in Java are: @Override, @Deprecated, @SuppressWarnings, @SafeVarargs, @FunctionalInterface, everyone should see these annotations No stranger, these are the five basic annotations in Java.

Java annotations can be generally understood as labeling. I can label a young person as youthful, energetic, passionate, idealistic, etc. These can be regarded as annotations for young people. It is understood that labels are characteristics and interpretations of certain aspects of things.

How to define annotations:

Defining annotations is implemented through the @interface keyword

public @interface Fruit {
}

The above code creates the Fruit annotation, which can be understood as a label named Fruit.

Using annotations: The method of using annotations is very simple. You can release annotations on classes or methods, depending on what you need this annotation to achieve. For example, annotating annotating classes

@Fruit
public class Annotest {
}

This puts the @Fruit tag on the Annotest class.

Seeing this, you may understand that an annotation is to put a label on a method, class, package, identify the class, and make the method and class have the identifier of the annotation, yes, that's right

Using custom annotations is not enough to do this, you also need to use meta-annotations in Java

Meta annotations:

Meta-annotation is a basic annotation that can be applied to annotations (it can be understood that meta-annotation is also a kind of label, but it is a special label, which can be a kind of annotation on the annotation body)

There are five kinds of annotations in Java, @Retention, @Documented, @Target, @Inherited, @Repeatable

@Retention: the meaning of retention, maintenance, retention, this annotation provides the life cycle of the annotation

The values ​​are as follows:

RetentionPolicy.SOURCE: Indicates that the annotation is only retained in the source code stage, and the compiler ignores and discards it

RetentionPolicy.CLASS: High annotations are retained until the compilation stage and are not loaded back into the jvm

RetentionPolicy.RUNTIME: The annotation is retained until runtime
@Documented: identifies that the annotation belongs to the document type, and its function is to include the elements in the annotation into javac
@Target: identifies the place where the annotation is used, and limits the usage scenarios of the annotation. The value of target is as follows:
ElementType.ANNOTATION_TYPE: You can annotate an annotation class
ElementType.CONSTRUCTOR: Annotate a constructor
ElementType.FIELD: Annotate property methods
ElementType.LOCAL_VARIABLE: Annotate local methods
ElementType.METHOD: Annotate the method
ElementType.PACKAGE: Annotate the package
ElementType.PARAMETER: Annotate parameters within a method
ElementType.TYPE: Annotate a type, including: class, interface, enumeration class
@Inherited: inheritance annotation, if a superclass uses this annotation and its subclass is not annotated by any annotation, then this subclass inherits the superclass's annotation
@Repeatable: An annotation added by jdk1.8, which means repeatable. Using this annotation means that the value of the annotation can take multiple values.

Annotation property:
Annotation has only member variables, no methods, member variables are properties, for example:
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.TYPE)
public @interface Fruit {
    int id();
    String msg();
}

This annotation defines two members: id and msg. When using it, we should assign a value to it

@Fruit(id = 1, msg = "anno")
public class TestAno {
}

The member type defined in the annotation must be 8 basic data types + class, interface, annotation, and annotation array

Member properties in annotations can also specify default values

  

@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.TYPE)
public @interface Fruit {
    int id() default 0;
    String msg() default "apple";
}

 

Get annotations:

  The original intention of using annotations is to label classes, methods, etc. in the code. What is its function? Of course, when obtaining a class or method, we can determine whether the class or method is the annotation type, and perform special operations and methods. Processing, then how to check and extract annotations, I believe you have already thought, that is to use the reflection mechanism in Java

Reflection to obtain annotations: The method in the Class class judges whether the isAnnotationPresent() method in the class judges whether to use the annotation, the getAnnotation() method obtains the annotation object, and the getAnnotations() method obtains all annotations

 

public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
        return GenericDeclaration.super.isAnnotationPresent(annotationClass);
    }

public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
Objects.requireNonNull(annotationClass);

return (A) annotationData().annotations.get(annotationClass);
}

  public Annotation[] getAnnotations() {} 

The following is an example of using reflection to obtain annotations:

  

@Fruit
public class Test {

    public static void main(String[] args) {
        boolean isAnno = Test.class.isAnnotationPresent(Fruit.class);
        if(isAnno) {
            Fruit annotation = Test.class.getAnnotation(Fruit.class);
            System.out.println(annotation.id());
            System.out.println(annotation.msg());
        }
    }
}

The result of running is of course: 0 apple

 

Next, let's see how to extract the annotations in the method's annotations

1. First define a property annotation: MyParamAnno

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyParamAnno {

    String value();
}

 

2. Define a method type annotation: MyMethodAnno

@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.METHOD)
public @interface MyMethodAnno {
}

 

3. An example of annotations on parsing method attributes:

@Fruit(msg = "skyline")
public class MethodAnnoTest {

    @MyParamAnno("hello")
    String param;

    @MyMethodAnno
    public void method(){}


    public static void main(String[] args) {
        boolean isAnno = MethodAnnoTest.class.isAnnotationPresent(Fruit.class);
        if (isAnno) {
            Fruit annotation = MethodAnnoTest.class.getAnnotation(Fruit.class);
            System.out.println(annotation.msg());
        }
        //Parse property method annotations
        try {
            Field param = MethodAnnoTest.class.getDeclaredField("param");
            param.setAccessible(true);
            //Get the annotation for the variable
            MyParamAnno paramAnno = param.getAnnotation(MyParamAnno.class);
            if(paramAnno != null) {
                System.out.println("The annotation value of the member property is:" + paramAnno.value());
            }

            //get method annotation
            Method method = MethodAnnoTest.class.getDeclaredMethod("method");
            if (method != null) {
                MyMethodAnno methodAnno = method.getAnnotation(MyMethodAnno.class);
                System.out.println("Method annotation:" + methodAnno.annotationType().getSimpleName());
            }

        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        
    }
}

 

The output result is:
skyline
 The annotation value of the member property is: hello
 Method annotation: MyMethodAnno

Summarize:

Comments are used to annotate and explain the code, but because of the reflection mechanism, it will affect the performance, so don't abuse it.

 

 

Tags: Java

Posted by sp0rk on Tue, 24 May 2022 01:39:44 +0300