Introduction to the Use of Annotations

This blog is mainly divided into the following questions

  1. Relevant Knowledge Points of Annotations
  2. Examples of runtime-based annotations

As for compile-time annotations, I'll give you some examples in the next blog, and I'm still learning about them.

Relevant Knowledge Points of Annotations

When it comes to annotations, most people should not default. The @Override, @Deprected, @SupressWarnings and so on, which we see in our program, are annotations. They are just packaged by the system itself, but we seldom understand how to implement them in depth.

1) What is Annotation?

Annotation is that Java provides a way and method for elements in metaprograms to associate any information with any metadata. Annotion is an interface. Programs can get Annotion objects of specified program elements by reflection, and then obtain metadata in annotations by Annotion objects.

2) Classification of annotations:

According to the number of annotation parameters, we can divide annotations into three categories:

  1. Markup annotations: An Annotation type without a member definition is called a markup annotation. This Annotation type only uses its own existence to provide us with information. For example, the following system annotation @Override;
  2. Single-valued annotations
  3. Complete annotations

According to the usage and use of annotations, we can classify Annotation into three categories:

  1. JDK built-in system annotations
  2. Meta-annotations
  3. Custom Annotations

3) Meta-annotations:

The function of meta-annotations is to annotate other annotations. Java 5.0 defines four standard meta-annotation types, which are used to provide descriptions of other annotation types. Meta-annotations defined in Java 5.0:

  1. @Target,
  2. @Retention,
  3. @Documented,
  4. @Inherited

4) Analytical explanation of meta-annotations

  • @ Documented will be saved in Javadoc documents
  • @ Retention retention time, optional value

SOURCE (source time), CLASS (compile time), RUNTIME (run time), default to CLASS, SOURCE is mostly Mark Annotation, such Annotations are mostly used for verification, such as Override, Suppress Warnings.

  • @ Target can be used to modify which program elements, such as TYPE, METHOD, CONSTRUCTOR, FIELD, PARAMETER, etc. Unmarked means that all can be modified.

    ANONOTATION_TYPE (Annotation Type Statement)
    PACKAGE (package)
    TYPE (class, including enum and interface, annotation type)
    METHOD (Method)
    CONSTRUCTOR (Construction Method)
    FIFLD (member variable)
    PARAMATER (parameter)
    LOCAL_VARIABLE (Local Variable)

  • @ Whether Inherited can be inherited by default to false

5) What is metadata?

Metadata is translated from the word metadata, which means "data about data".
 
Metadata has many functions, such as: you may have used Javadoc annotations to automatically generate documents. This is one of the metadata functions. In general, metadata can be used to create documents, track code dependencies, and perform compile-time format checks instead of existing configuration files. If we want to classify the role of metadata, there is no clear definition at present, but we can roughly classify it into three categories according to its role:

  1. Writing Documents: Generating Documents from Metadata Identified in Code
  2. Code analysis: Code analysis through metadata identified in the code
  3. Compilation Check: Allows the compiler to perform basic compilation checks by identifying metadata in the code

Other knowledge points are not introduced for the time being. I find it difficult to digest too many concepts introduced at once. Let's use it with examples.

Let's take a look at how we can write an example of a custom comment based on compile time

Custom annotations can be roughly divided into three steps:

  1. Customize a comment
  2. Use our annotations in other classes
  3. Resolve our annotations at runtime

Analytical Operating Flow Chart

1) First let's see how we can customize a comment.

These types and the classes they support can be found in the java.lang.annotation package.

/* 
 * Definition annotation MethodInfo 
 * To facilitate testing: Annotation aims at class methods, attributes, and construction methods 
 * The annotations contain three elements id, name and gid. 
 * id Elements have a default value of 0
 */ 

@Documented 
@Target({ElementType.TYPE,ElementType.METHOD,
    ElementType.FIELD,ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MethodInfo {
    String name() default "xujunTest";
    int id() default 0;
    Class<Long> gid();
}

Analytical explanation

  • (1) Through the @interface definition, the annotation name is a custom annotation name, where the annotation name is MethodInfo
  • (2) The annotation configuration parameter is the method name of the annotation class, and:

    a. All methods have no method body, no parameter and no modifier. Actually, only the public & Abstract modifier is allowed. By default, the public modifier is not allowed to throw exceptions.

    b. Method return values can only be basic types, String, Class, annotation, enumeration, or their one-dimensional array

    c. If there is only one default attribute, the value() function can be used directly. None of the attributes indicates that the Annotation is Mark Annotation

  • (3). Default values can be represented by default, such as
String name() default "xujunTest";

2) Then let's see how we can use our custom annotations.

/**
 * This class is dedicated to testing the use of annotations
 * @author xujun
 */
 //Class member annotations
@MethodInfo (name="type",gid=Long.class) 
public class UserAnnotation {
    //Class member annotations
    @TestA(name="param",id=1,gid=Long.class) 
    private Integer age;
    
    //Annotation of Construction Method
    @TestA (name="construct",id=2,gid=Long.class)
    public UserAnnotation(){
        
    }
    
    //Class Method Annotation
    @TestA(name="public method",id=3,gid=Long.class)      
    public void a(){
        Map<String,String> m = new HashMap<String,String>(0);
    }
    
    //Class Method Annotation
    @TestA(name="protected method",id=4,gid=Long.class) 
    protected void b(){
        Map<String,String> m = new HashMap<String,String>(0);
    }
    
    //Class Method Annotation
    @TestA(name="private method",id=5,gid=Long.class) 
    private void c(){
        Map<String,String> m = new HashMap<String,String>(0);
    }
    
    public void b(Integer a){ 
        
    }
}

3) Finally, let's take a look at how we can parse our Annotation annotations at runtime.

Runtime Annotation parsing

(1) Runtime Annotation refers to @Retention as RUNTIME Annotation, which can manually call the following commonly used API parsing

method.getAnnotation(AnnotationName.class);
method.getAnnotations();
method.isAnnotationPresent(AnnotationName.class);

Other @Target methods such as Field and Class are similar

  • getAnnotation(AnnotationName.class) represents information about an Annotation of the Target, because a Target can be modified by multiple Annotations.
/*
* Returns a specified type annotation of a method based on the annotation type
*/
MethodInfo annotation = (MethodInfo) constructor
                     .getAnnotation(MethodInfo.class);
  • getAnnotations() indicates that all Annotations of the Target are obtained.
Annotation[] annotations = clazz.getAnnotations();
for (Annotation annotation : annotations) {
    MethodInfo methodInfo = (MethodInfo) annotation
}
  • isAnnotationPresent(AnnotationName.class) indicates whether the Target is modified by an Annotation
/*
* Determine whether there are annotations of a specified annotation type in the construction method
*/
boolean hasAnnotation = constructor
.isAnnotationPresent(MethodInfo.class);
if (hasAnnotation) {
    /*
    * Returns a specified type annotation of a method based on the annotation type
    */
    MethodInfo annotation = (MethodInfo) constructor
    .getAnnotation(MethodInfo.class);
}

Test code

public class ParseAnnotation {
    
    static String className="com.xujun.animation.test.UserAnnotation";
    /**
     * Simply print class annotations used in UserAnnotation classes. This method prints only Type annotations.
     * 
     * @throws ClassNotFoundException
     */
    public static void parseTypeAnnotation() throws ClassNotFoundException {
        Class clazz = Class.forName(className);

        Annotation[] annotations = clazz.getAnnotations();
        for (Annotation annotation : annotations) {
            MethodInfo testA = (MethodInfo) annotation;
            System.out.println("id= \"" + testA.id() + "\"; name= \""
                    + testA.name() + "\"; gid = " + testA.gid());
        }
    }

    /**
     * Simply print out Method annotations used in the UserAnnotation class. This Method prints only Method-type annotations.
     * 
     * @throws ClassNotFoundException
     */
    public static void parseMethodAnnotation() {
        Method[] methods = UserAnnotation.class.getDeclaredMethods();
        for (Method method : methods) {
            /*
             * Judging whether there are annotations of specified annotation type in the method
             */
            boolean hasAnnotation = method.isAnnotationPresent(MethodInfo.class);
            if (hasAnnotation) {
                /*
                 * Returns a specified type annotation of a method based on the annotation type
                 */
                MethodInfo annotation = method.getAnnotation(MethodInfo.class);
                System.out.println("method = " + method.getName() + " ; id = "
                        + annotation.id() + " ; description = "
                        + annotation.name() + "; gid= " + annotation.gid());
            }
        }
    }

    /**
     * Simply print out Method annotations used in the UserAnnotation class. This Method prints only Method-type annotations.
     * 
     * @throws ClassNotFoundException
     */
    public static void parseConstructAnnotation() {
        Constructor[] constructors = UserAnnotation.class.getConstructors();
        for (Constructor constructor : constructors) {
            /*
             * Determine whether there are annotations of a specified annotation type in the construction method
             */
            boolean hasAnnotation = constructor
                    .isAnnotationPresent(MethodInfo.class);
            if (hasAnnotation) {
                /*
                 * Returns a specified type annotation of a method based on the annotation type
                 */
                MethodInfo annotation = (MethodInfo) constructor
                        .getAnnotation(MethodInfo.class);
                System.out.println("constructor = " + constructor.getName()
                        + " ; id = " + annotation.id() + " ; description = "
                        + annotation.name() + "; gid= " + annotation.gid());
            }
        }
    }

    public static void main(String[] args) throws ClassNotFoundException {
        parseTypeAnnotation();
        parseMethodAnnotation();
        parseConstructAnnotation();
    }
}

Running the above test program, you will see the following output

id= "0"; name= "type"; gid = class java.lang.Long
method = c ; id = 5 ; description = private method; gid= class java.lang.Long
method = b ; id = 4 ; description = protected method; gid= class java.lang.Long
method = a ; id = 3 ; description = public method; gid= class java.lang.Long
constructor = com.xujun.animationdemo.UserAnnotation ; id = 2 ; description = construct; gid= class java.lang.Long

Reprinted please indicate The original blog address:

Source download address:

Relevant Blog Recommendations

Detailed explanation of java Type

Detailed explanation of java reflection mechanism

Introduction to the Use of Annotations (I)

Android custom compile-time annotation 1 - simple example

Android Compile-time Annotations - Syntax Details

Take you to read ButterKnife's source code

Sweep it out. Welcome to my Wechat public number stormjun94 (Xugong Code Word). Now I am a programmer. I not only share the knowledge of Android development, but also share the growth process of technicians, including personal summary, career experience, interview experience, etc. I hope you can take less detours.

Tags: Android Java JDK Attribute

Posted on Thu, 10 Oct 2019 04:48:41 -0700 by mrjam