目录

  • 一、自定义注解
  • 1.使用 @interface 来定义你的注解
  • 2.使用 @Retention 注解来声明自定义注解的生命周期
  • 3.使用 @Target 注解来声明注解的使用范围
  • 4.添加注解的属性
  • 二、使用自定义的注解
  • 1.将注解注在其允许的使用范围
  • 2.使用反射获取类成员变量上的所有注解
  • 3.反射获取成员变量上的指定注解
  • 4.获取方法上的指定注解


一、自定义注解

1.使用 @interface 来定义你的注解

我们定义一个类的时候是使用的 class 关键字定义的,现在我们想定义一个自己的注解 需要使用 @interface 关键字来定义。

如定义一个叫 MyAnnotation 的注解:

public @interface MyAnnotation { }

2.使用 @Retention 注解来声明自定义注解的生命周期

@Retention 用来指定注解的生命周期(源码、class文件、运行时),其可选值如下:

● RetentionPolicy.SOURCE : 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
● RetentionPolicy.CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。
● RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。

声明 MyAnnotation 注解的生命周期是 RetentionPolicy.RUNTIME:

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation { 
}

3.使用 @Target 注解来声明注解的使用范围

@Target 用来声明注解可以用在哪些地方(类上、类成员变量上、方法上、参数上等),其可选值如下:

● ElementType.CONSTRUCTOR :用于描述构造器。
● ElementType.FIELD :成员变量、对象、属性(包括enum实例)。
● ElementType.LOCAL_VARIABLE: 用于描述局部变量。
● ElementType.METHOD : 用于描述方法。
● ElementType.PACKAGE :用于描述包。
● ElementType.PARAMETER:用于描述参数。
● ElementType.ANNOTATION_TYPE:用于描述参数
● ElementType.TYPE :用于描述类、接口(包括注解类型) 或enum声明。

声明 MyAnnotation 注解可用于类成员变量和方法上:

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD)
public @interface MyAnnotation { 
}

4.添加注解的属性

为 MyAnnotation 注解添加 id 和 describe 属性:

package com.hai.tang.annotation;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD)
public @interface MyAnnotation { 
    int id();
    String describe();
}

也可以为 id 和 describe 属性添加默认值,当 id 或 describe 属性不指定具体的值的时候就会使用默认值:

package com.hai.tang.annotation;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD)
public @interface MyAnnotation { 
    int id() default 0;
    String describe() default "";
}

到这里你已经完整定义了一个叫 MyAnnotation 的注解,其声明周期是运行时,可注解在类成员变量和方法上,拥有 id 和describe 两个属性并拥有默认值。

二、使用自定义的注解

1.将注解注在其允许的使用范围

上面 MyAnnotation 注解,可注解在类成员变量和方法上。

package com.hai.tang.model;

import com.alibaba.fastjson2.annotation.JSONField;
import com.hai.tang.annotation.MyAnnotation;

public class Student {

    @JSONField(ordinal =0)
    @MyAnnotation
    public String name;

    @MyAnnotation(id=1,describe="分数")
    public Integer score;

    public Student() {
    }

    @MyAnnotation(describe="getName方法")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getScore() {
        return score;
    }

    public void setScore(Integer score) {
        this.score = score;
    }
}

2.使用反射获取类成员变量上的所有注解

import com.hai.tang.annotation.MyAnnotation;
import com.hai.tang.model.Student;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;

public class MainServer {
    public static void main(String[] args) {
        Class<?> studentClass = Student.class;
        Field[] fields = studentClass.getDeclaredFields();//获取所有的类成员变量字段
        for (Field field : fields) {
            String fieldName = field.getName(); //获取该类成员变量的名字
            System.out.println("成员变量名是:" + fieldName);
            Annotation[] annotations = field.getAnnotations(); //获取该类成员变量上所有声明周期是运行时的注解
            for (Annotation annotation : annotations) {
                Class<? extends Annotation> annotationType = annotation.annotationType();
                String annotationName = annotationType.getSimpleName();//注解的简短名称
                System.out.println(" 使用的注解是:" + annotationName);
                //判断该注解是不是 MyAnnotation 注解,是的话打印其 id 和 describe 属性
                if (annotationType.equals(MyAnnotation.class)) {
                    MyAnnotation myAnnotation = field.getAnnotation(MyAnnotation.class);
                    int id = myAnnotation.id();
                    String describe = myAnnotation.describe();
                    System.out.println("    MyAnnotation注解中的id是:" + id);
                    System.out.println("    MyAnnotation注解中的describe是:" + describe);
                }
            }
            System.out.println();
        }
    }
}

输出:

成员变量是:name
 使用的注解是:JSONField
 使用的注解是:MyAnnotation
    MyAnnotation注解中的id是:0
    MyAnnotation注解中的describe是:

成员变量是:score
 使用的注解是:MyAnnotation
    MyAnnotation注解中的id是:1
    MyAnnotation注解中的describe是:分数

3.反射获取成员变量上的指定注解

import com.hai.tang.annotation.MyAnnotation;
import com.hai.tang.model.Student;
import java.lang.reflect.Field;

public class MainServer {
    public static void main(String[] args) {
        Class<?> studentClass = Student.class;
        //反射遍历所有成员变量
        Field[] fields = studentClass.getDeclaredFields();
        for (Field field : fields) {
            //如果其成员变量上有 MyAnnotation 注解,就打印成员变量名和注解里的内容
            if (field.isAnnotationPresent(MyAnnotation.class)) {
                String fieldName = field.getName();
                //获取变量字段上的 MyAnnotation 注解
                MyAnnotation annotation = field.getAnnotation(MyAnnotation.class);
                int id = annotation.id();
                String describe = annotation.describe();
                System.out.println("成员变量是:" + fieldName);
                System.out.println("MyAnnotation注解中的id是:" + id);
                System.out.println("MyAnnotation注解中的describe是:" + describe);
            }
            System.out.println();
        }
    }
}

输出:

成员变量是:name
MyAnnotation注解中的id是:0
MyAnnotation注解中的describe是:

成员变量是:score
MyAnnotation注解中的id是:1
MyAnnotation注解中的describe是:分数

4.获取方法上的指定注解

import com.hai.tang.annotation.MyAnnotation;
import com.hai.tang.model.Student;
import java.lang.reflect.Method;

public class MainServer {
    public static void main(String[] args) {
        Class<?> studentClass = Student.class;
        //反射遍历所有方法
        Method[] methods = studentClass.getDeclaredMethods();
        for (Method method : methods) {
            //如果其方法上有 MyAnnotation 注解,就打印方法名和注解里的内容
            if (method.isAnnotationPresent(MyAnnotation.class)) {
                String methodName = method.getName();
                //获取方法上的 MyAnnotation 注解
                MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
                int id = annotation.id();
                String describe = annotation.describe();
                System.out.println("方法名是:" + methodName);
                System.out.println("MyAnnotation注解中的id是:" + id);
                System.out.println("MyAnnotation注解中的describe是:" + describe);
            }
        }
    }
}

输出:

方法名是:getName
MyAnnotation注解中的id是:0
MyAnnotation注解中的describe是:getName方法