I wrote a Java annotation article before, but I didn’t have much understanding of annotation application at that time, and some knowledge points were not fully understood. I recently looked at the Retrofit source code to further understand the use of annotations. This article is a review of the previous knowledge and a supplementary explanation of the use of annotations.

What are annotations for

Annotations are like tags that mark your code, and can be understood as special modifiers that apply to classes, methods, parameters, variables, constructors, and packages.


I understand the role of annotations, generally have the following three applications


1. Provide information to the compiler: The compiler can use annotations to detect errors and warnings

A typical example of this is the @Override annotation, which marks method overrides and is discarded during source compilation.

2. Compilation stage processing: Software tools can use annotation information to automatically generate code, HTML documents, and other corresponding processing

For example, annotations in the ButterKnife framework use compile-generated code (APT) techniques.

3. Runtime processing: Some annotations can receive code extraction while the program is running, providing a logical basis for the program to judge or logical processing basis

For example, @get and @Post annotations that are custom defined by the Retrofit framework are parsed while processing the request logic to implement the relevant request logic.

How to declare annotations


format

@ yuan notespublic @interfaceAnnotation name {attribute list;// No
}
Copy the code

nature

Annotations are at the same level as classes, interfaces, and enumerations.

Annotation is the nature of an inheritance. Java lang. The annotation. The annotation interface interface

attribute

  1. Attribute declaration:

    Attributes of annotations, also called member variables

    Q: Since an annotation is essentially an interface, and we all know that interfaces cannot define member variables, what are the attributes of the annotation?

    @Documented
    @Target(METHOD)
    @Retention(RUNTIME)
    public @interface GET {
      String value(a) default "";
    }
    Copy the code

    In Retrofit’s @GET example, we can see that the attribute of the annotation actually corresponds to the interface method. In annotations we call things like String value() properties. Obviously assigning to ‘attributes’ sounds a lot more palatable than assigning to methods.

    A: The attributes of annotations are defined in the definition of annotationsNo arguments methodThe method name is the property name, and the return value is the type of the property.

    The attribute type of the annotation must be the following:

    Eight basic types (Byte, Boolean, char, short, int, Long, float, double) and String, Enum, Class, annotation types, as well as arrays of these types

  2. Attribute assignment

    Attribute is assigned toThe attribute name = XXXMultiple attributes are assigned to.Separated.

    Attributes of annotations can be passeddefaultThe keyword specifies the default value. If a default value is specified, it can be used without assigning a value. Otherwise, the value must be explicitly assigned

    If the annotation has only one property namedvalueYou can omit the attribute name when assigning

    Take the @get annotation above:

    @GET(value = "1111")
    void testAssign2(a);
    
    // or omit value
    @GET("1111")
    void testAssign1(a);
    Copy the code

Yuan notes

Another very important concept for annotation declarations is the meta-annotation.

Meta-annotations are basic annotations that can be used to annotate other annotations; Think of it as a special modifier used to explain annotations.

Common meta-annotations are as follows:

  1. @Retention

    Description: Used to identify the lifetime of an annotation

    Values:

    public enum RetentionPolicy {
     /** * annotations are retained only at the source stage and discarded at compile time */
     SOURCE,
    
     /** * annotations are kept in the Class file, but are discarded by the JVM at runtime */
     CLASS,
    
     /** * annotations are retained in the Class file and are also retained at runtime
     RUNTIME
     
     }
    Copy the code
  2. @Documented

    Note: Used to indicate that annotations can be used as public apis that can be extracted into documentation by tools such as Javadoc. @documented is just a marker, no attribute.

  3. @Target

    Description: Used to restrict the application scenario of the current annotation (class, method, etc.), default is not restricted if not used.

    @TargetThe array type is array, so multiple values are assigned at the same time.In {}, multiple values are separated by commas. If only one value is assigned, {} can be omitted.

    Example:

     @Target({METHOD, PARAMETER, FIELD})
     public @interface FontRes {
     }
    Copy the code

    Values:

    public enum ElementType {
     /** class, interface (including annotations), enumeration */
     TYPE,
    
     /** attributes (including enumeration constants) */
     FIELD,
    
     / * / * * method
     METHOD,
    
     /** Method argument */
     PARAMETER,
    
     /** constructor */
     CONSTRUCTOR,
    
     /** Local variable */
     LOCAL_VARIABLE,
    
     / * comment * /
     ANNOTATION_TYPE,
    
     / * * * /
     PACKAGE,
    
     /** ** is used for type parameter declarations. Java8 adds */
     TYPE_PARAMETER,
    
     /** ** where types are used, Java8 adds */
     TYPE_USE
     }
    Copy the code
  4. @Inherited

    Description: allows subclasses to inherit the current annotation. If a superclass is decorated with the current annotation, its subclasses also have the annotation. @interited has no attribute value.

    Note: A class cannot inherit annotations from the interface it implements, nor can a method inherit annotations from the method it overloads

  5. @Repeatble

    Used to mark the current annotation can be repeated, java1.8 new feature. This can be done with @REPEATable if the same annotation needs to be used multiple times in the same scenario

    Example:

     /** Custom container annotation Roles(used to hold other annotations, must have a value attribute in it@RepeatableAnnotated array of annotations) */
     @Target(ElementType.TYPE)
     @Retention(RetentionPolicy.RUNTIME)
     public @interface Roles {
     Role[] value();
     }
    
     /** Custom annotation Role, use@RepeatableAnnotations, so that the Role annotation can be used multiple times */
     @Repeatable(Roles.class)
     public @interface Role {
     String role(a) default "";
     }
    
     // An example
     @Role(role="husband")
     @Role(role="father")
     @Role(role="son")
     public class Person {}Copy the code

How to use annotations

By use, I mean not just the use of simple meanings, but also the reading of annotations, giving them real meaning

Notes are divided into:

  • Built-in JDK annotations such as @Override, @deprecated, and so on are read and processed by the compiler to implement what they actually represent

  • Annotations provided by third-party frameworks, such as @get, @Post, etc. from Retrofit, will be read and processed to give them real meaning

  • Custom annotations: These are the kind of annotations we need to read ourselves to give them real meaning. Otherwise there is no point in declaring annotations and using them in the context (methods, parameters, etc.).

There are two ways to extract and use custom annotations

  1. Scan and process annotations (APT, Annotation Processing Tool) at compile time. For details, see Java Annotation application

  2. The runtime scans and processes annotations (via Java reflection related apis). Take a look at Retrofit’s use of runtime annotations, and consider writing an example later on.