Annotations and meta-annotations to learn a little every day

annotation

1. Annotation Overview

Definition :
Annotation, also called metadata. It is at the same level as classes, interfaces, and enumerations. It can be declared in front of packages, classes, fields, methods, local variables, method parameters, etc., to explain and comment on these elements.

Function classification :

  • Write documentation: Generate documentation through the annotations identified in the code [for example, generate documentation doc documents]
  • Code analysis: analyze the code through the annotations identified in the code [for example, the reflection of annotations]
  • Compilation check: Through the annotations identified in the code, the compiler can implement basic compilation checks [for example, Override]

Common Notes

  1. @author : used to identify the author name
  2. @version : The version number used to identify the object, applicable scope: files, classes, methods.
  3. @Override : Used to modify the method declaration, telling the compiler that the method is to override the method in the parent class. If the method does not exist in the parent class, the compilation will fail.

2. Custom annotations

define format

meta-annotation
public @interface annotation-name { property-list; }

Any annotation is essentially an interface, which inherits the Annotation interface by default.

public @interface MyAnno extends java.lang.annotation.Annotation {}

3. Properties of annotations

  1. The role of the attribute =

    • Allows users to pass parameters when using annotations, making annotations more powerful.
  2. format of attributes

    • Format 1: data type attribute name();
    • Format 2: data type attribute name () default default value;
  3. Property definition example

    public @interface Student { String name(); // name int age() default 18; // age String gender() default "male"; // gender } // This annotation has three attributes: name, age , gender




The data type to which the attribute applies

  • Eight basic data types ( int, float, boolean, byte, double, char, long, short ).
  • String type, Class type, enumeration type, annotation type.
  • One-dimensional arrays of all the above types.

4. Use custom annotations

Steps for using (parsing) annotations in a program (obtaining attribute values ​​​​defined in annotations):

  1. Get the object of the location defined by the annotation (Class, Method, Field)
  2. Get the specified annotationgetAnnotation(Class)
  3. Call the abstract method in the annotation to get the configured attribute value

@Annotation name (property name=property value, property name=property value, property name=property value...)

Precautions for use

  • If the attribute has a default value, when using annotations, this attribute does not need to be assigned.
  • If the attribute has no default value, then be sure to assign a value to the attribute when using the annotation.
  • If the attribute is an array type, you don’t need to write curly braces when only assigning one value when using it, but you need to use curly braces when there are multiple values.
special attribute value
  1. When there is only one attribute in the annotation and the name is value, assigning a value to the value attribute when using the annotation can directly give the attribute value, regardless of whether the value is a single-value element or an array type.
// 定义注解Book
public @interface Book {
    
    
    // 书名
    String value();
}

// 使用注解Book
public class BookShelf {
    
    
    @Book("西游记")
    public void showBook(){
    
    

    }
}
public class BookShelf {
    
    
    @Book(value="西游记")
    public void showBook(){
    
    

    }
}
  1. If there are other attributes in the annotation besides the value attribute, and at least one attribute has no default value, the name of the value attribute cannot be omitted when using the annotation to assign a value to the attribute.
// 定义注解Book
public @interface Book {
    
    
    // 书名
    String value();
    // 价格
    double price() default 100;
    // 多位作者
    String[] authors();
}
// 使用Book注解:正确方式
@Book(value="红楼梦",authors = "曹雪芹")
public class BookShelf {
    
    
  // 使用Book注解:正确方式
    @Book(value="西游记",authors = {
    
    "吴承恩","白求恩"})
    public void showBook(){
    
    

    }
}

// 使用Book注解:错误方式
public class BookShelf {
    
    
    @Book("西游记",authors = {
    
    "吴承恩","白求恩"})
    public void showBook(){
    
    

    }
}
// 此时value属性名不能省略了。

5. Meta-comments of annotations

1. @Target of meta-annotation

Function: Indicate where this annotation is used. If it is not written, it can be used anywhere by default.

  • Optional parameter values ​​in the enumeration class ElemenetType include:

TYPE: Used on classes and interfaces
FIELD: Used on member variables
METHOD: Used on methods
PARAMETER: Used on parameters
CONSTRUCTOR: Used on construction methods
LOCAL_VARIABLE: Used on local variables

2. @Retention of meta-annotation

Role: Define the life cycle (valid range) of the annotation.

  • Optional parameter values ​​include in the enumeration type RetentionPolicy

SOURCE: Annotations only exist in the Java source code, not in the compiled bytecode file.
CLASS: The annotation exists in the Java source code and the bytecode file after compilation, but it does not exist in the memory when running, the default value.
RUNTIME: The annotation exists in the Java source code, in the compiled bytecode file, and in the runtime memory, and the program can obtain the annotation through reflection.

6. Annotation analysis

The process of obtaining annotation data through Java technology is called annotation analysis.

Interfaces related to annotation parsing

  • Anontation : The public interface of all annotation types, similar to the parent class of all classes is Object.
  • AnnotatedElement : Defines methods related to annotation parsing. There are four commonly used methods:

boolean isAnnotationPresent(Class annotationClass); Determine whether the current object has the specified annotation, return true if yes, otherwise return false.
T getAnnotation(Class annotationClass); Get the annotation object specified on the current object.
Annotation[] getAnnotations(); Get the current object and all annotation objects inherited from the parent class.
Annotation[] getDeclaredAnnotations(); Get all annotation objects on the current object, excluding the parent class.

The principle of obtaining annotation data: On which member the annotation acts on, the object of the member is obtained through reflection to get its annotation.

If the annotation acts on the class, its annotation is obtained through the Class object.

// Obtain the Class object
Class c = class name.class;
// Obtain the annotation object used on the class according to the annotated
Class Book book = c.getAnnotation(Book.class);

If the annotation acts on the method, get its annotation through the method (Method) object.

// Get the method object
Method method = clazz.getDeclaredMethod("Method Name");
// Get the annotation object on the method according to the annotation name
Book book = method.getAnnotation(Book.class);

7. Use reflection to get annotation data

Statement of needs
  1. To define the annotation Book, the requirements are as follows:
    • Contains attributes: String value() book title
    • Include attribute: double price() price, the default value is 100
    • Contains attributes: String[] authors() multiple authors
    • Limit where annotations can be used: on classes and member methods
    • Specify the effective range of annotations: RUNTIME
  2. Define the BookStore class and use Book annotations on the class and member methods
  3. Define the TestAnnotation test class to obtain the data on the Book annotation

Annotation Book

@Target({
    
    ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Book {
    
    
    // 书名
    String value();
    // 价格
    double price() default 100;
    // 作者
    String[] authors();
}

BookStore class

@Book(value = "红楼梦",authors = "曹雪芹",price = 998)
public class BookStore {
    
    
}

TestAnnotation class

public class TestAnnotation {
    
    
public static void main(String[] args)  throws Exception{
    
    
        System.out.println("---------获取类上注解的数据----------");
        test();
    }

    /**
     * 获取BookStore类上使用的Book注解数据
     */
    public static void test(){
    
    
        // 获得BookStore类对应的Class对象
        Class c = BookStore.class;
        // 判断BookStore类是否使用了Book注解
        if(c.isAnnotationPresent(Book.class)) {
    
    
            // 根据注解Class对象获取注解对象
            Book book = (Book) c.getAnnotation(Book.class);
            // 输出book注解属性值
            System.out.println("书名:" + book.value());
            System.out.println("价格:" + book.price());
            System.out.println("作者:" + Arrays.toString(book.authors()));
        }
}

Guess you like

Origin blog.csdn.net/qq_52370789/article/details/129426060