Before learning annotations, I will first talk about the benefits of learning annotations. Whether you read the following or not, just give me some encouragement. However, it is certain that in normal JAVA development, few people write their own annotations. In most cases, they use annotations from third-party libraries. Because of this, most developers only know how to use annotations. Imagine that if you know how to use annotations when most people don’t, then you have surpassed most people. In addition, I also summarize the three major benefits of learning annotations:

  1. Able to understand code written by others, especially framework-related code;
  2. Make programming more concise and the code clearer;
  3. Let others look up to you, a powerful tool for showing off;

Having said all this, let’s start talking about the real stuff.

Annotation Concept

JDK 5 introduced the mechanism of annotation in source code. Annotation allows Java source code to contain not only functional implementation code, but also metadata. The function of annotation is similar to that of comments in code, but the difference is that annotation does not provide a description of the code function, but is an important part of realizing program functions.

Common annotations in Java

For common annotations, you can understand them by just looking at the annotations that pop up in the IDE when developing JAVA. For JDK annotations, we must be very familiar with them.

JDK comes with annotations

  • @Override
  • @Deprecated
  • @Suppvisewarnings

Common third-party annotations

  • Spring
    • @Autowired
    • @Service
    • @Repository
  • Mybatis
    • @InsertProvider
    • @UpdateProvider
    • @Options

Classification of annotations

Classification by operating mechanism

  • Source code annotations (annotations only exist in the source code and are compiled into.class will not exist after being compiled into files)
  • Compile-time annotations (annotations in source code and.class exist in both source code and files, the above three JDK annotations are compile-time annotations)
  • Runtime annotations (annotations that still work during the runtime and even affect the runtime logic, for example @Autowired)

Sort by source

  • Annotations from JDK
  • Notes from third parties
  • Custom Annotations

Meta Annotation

Annotations for annotations

Custom Annotations

The following is a typical annotation declaration. Let’s take a look at it first. The following will explain the precautions for defining annotations:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description {
    String desc();
    String author();
    int age() default 18;
}

  1. use@interfaceDefining annotations
  2. Members (variables) are declared without parameters and without exceptions
  3. Can usedefault specify a default value for a member
  4. The types of members in annotations are restricted. Legal types include basic data types as well as StringClassAnnotationandEnumeration
  5. If the annotation has only one member, the member name should be value(), and the member name and assignment number can be omitted when used (= the member name and assignment sign ( )
  6. An annotation class can have no members. An annotation without members is called an identification annotation.
  7. Meta-annotation, used to annotate annotations, such as Descriptionthe 4 annotations above

Commonly used meta annotations

Target

Identifies the scope of the annotation. The scopes are as follows, covering almost all types of JAVA:

  1. ElementType.CONSTRUCTOR:Construction method
  2. ElementType.FIELD: Field
  3. ElementType.LOCAL_VARIABLE: Local variables
  4. ElementType.METHOD:method
  5. ElementType.PACKAGE:Bag
  6. ElementType.PARAMETER: Parameters
  7. ElementType.TYPE: Class, Interface

For example, the example above identifies Descriptionmethods and classes or interfaces that can be annotated:

@Target({ElementType.PARAMETER, ElementType.TYPE})

Retention

Identifies the life cycle of an annotation. There are three values:

  1. RetentionPolicy.SOURCE: Only displayed in source code, discarded during compilation
  2. RetentionPolicy.CLASS: It will be recorded classin the file during compilation and ignored during runtime
  3. RetentionPolicy.RUNTIME: exists at runtime and can be read through reflection

For example, the example above indicates that Descriptionthe data can be recorded to classa file, but will be ignored at runtime:

@Retention(RetentionPolicy.CLASS)

Inherited

Identifying meta-annotation, indicating that the annotation is allowed to be inherited by subclasses. Note that this is not the inheritance of annotations, nor is there inheritance between annotations. What this means is that if this annotation is used on a class (not an interface) declaration, then when a subclass inherits from this class, it will also have the same annotation as the parent class.

Documented

This annotation will be included when generating JAVA DOC.

Using custom annotations

The syntax for using annotations is:

The member names correspond to the members in the annotation, for example:

@Description(desc="description", author="swifter", age=18)
public String getColor() {
    return "red";
}

The above is just a simple example. Here is a detailed usage of annotations, which is also the way used in normal development. For annotations, a declaration has been given in the above code. Here are two classes to use the annotations. Through these two examples, it is obvious how to use annotations.

First class Person:

@Description(desc="person interface", author="swifter")
public abstract class Person {
    @Description(desc="method getName", author="swifter")
    abstract String getName();
    abstract void doSomething();
}

The second class Childinherits from Person:

public class Child extends Person {

    @Override
    @Description(desc="child method getName", author="swifter")
    public String getName() {
        return "get child";
    }

    @Override
    public void doSomething() {
        System.out.println("do something in child class");
    }
}

Parsing Annotations

Now that the annotation has been defined, we should consider how to parse the annotation in the code. Parsing annotations is to obtain the runtime annotation information on the class, function or member through reflection, so as to implement the logic of dynamically controlling the program operation. The main way of parsing is to Classobtain the annotation through the object through reflection, and then get the annotated field for operation. For example, the following example:

Class<Child> clazz = Child.class;

if(clazz.isAnnotationPresent(Description.class)) {
    Description description = clazz.getAnnotation(Description.class);
    System.out.println(description.desc()+" : "+description.author());
}

Method[] methods = clazz.getMethods();
for(Method method : methods) {
    if(method.isAnnotationPresent(Description.class)) {
        Description description = method.getAnnotation(Description.class);
        System.out.println(description.desc()+" : "+description.author());
    }
}

After running, the client will give the following results:

person interface : swifterchild method getName : swifter

The first line shows the annotation information on the class, and the second line shows the annotation information on the method. As can be seen in the code, both of these annotated objects are obtained through reflection. Although reflection is relatively slow in efficiency, considering the advantages brought by annotations, it is still necessary to master annotations.

Leave a Reply

Your email address will not be published. Required fields are marked *