自定义注解案例及相关知识

1. 四个元注解

  1. @Target:用于描述注解的使用范围

通过枚举类ElementType的10个常量来指定使用范围:
TYPE(类,接口), FIELD(属性),METHOD(方法),PARAMETER(形参),CONSTRUCTOR(构造器),
LOCAL_VARIABLE(局部变量),ANNOTATION_TYPE(注释类型),PACKAGE(包),TYPE_PARAMETER(类型参数),TYPE_USE(使用类型)

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * 返回可应用注释类型的元素类型的数组。
     */
    ElementType[] value();
}
  1. @Retention:用于描述注解的生命周期

通过枚举类RetentionPolicy的3个常量来指定
SOURCE(源代码):注释将被编译器丢弃
CLASS(字节码):注释将由编译器记录在类文件中,但不需要在运行时由VM保留。这是默认行为。
RUNTIME(运行时):注释将由编译器记录在类文件中,并在运行时由VM保留,因此它们可能被反射地读取。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * 返回retention 代理
     */
    RetentionPolicy value();
}
  1. @Documented:指示带有类型的注释默认情况下由javadoc和类似工具记录。
  2. @Inherited:表示自动继承注释类型

2. 自定义注解格式

[元注解]
[修饰符] @interface 注解名{
	[成员列表]
}

返回值类型只能是八种基本数据类型、String类型、Class类型、enum类型、Annotation类型、及其数组类型

如果自定义注解含有抽象方法,除非它有默认值,否则使用时必须指定返回值。格式为“方法名 = 返回值”,如果只有一个抽象方法(建议使用方法名value)需要赋值,且方法名为value,可以省略“value=”。

3. 自定义注解案例

自定义注解MyAnnotation111
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
//用来给学生的性别赋值
public @interface MyAnnotation {
    String value();
}
自定义注解MyAnnotation222
@Documented
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
//用来给学生的stuId和stuName赋值
public @interface MyAnnotation222 {
    String stuId();
    String stuName();
}
自定义类Student
@MyAnnotation222(stuName = "张三", stuId = "20240101023505")
public class Student {
    private String stuName;
    private String stuId;

    @MyAnnotation111("人妖")
    private String gender;

    //构造器
    public Student(String stuName, String stuId, String gender) {
        this.stuName = stuName;
        this.stuId = stuId;
        this.gender = gender;
    }
    public String getStuName() {
        return stuName;
    }
    public void setStuName(String stuName) {
        this.stuName = stuName;
    }
    public String getStuId() {
        return stuId;
    }
    public void setStuId(String stuId) {
        this.stuId = stuId;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Student{" +
                "stuName='" + stuName + '\'' +
                ", stuId='" + stuId + '\'' +
                ", gender=" + gender +
                '}';
    }

	//最核心的代码,用来获取Student对象的性别注释,并将性别值修改为注释的value值
    public static Student modifyGender(Student student) throws IllegalAccessException {
        // 获取User类中所有的属性(getFields无法获得private属性)
        Field[] fields = Student.class.getDeclaredFields();
        // 遍历所有属性
        for (Field field : fields) {
            // 如果属性上有此注解,则进行赋值操作
            if (field.isAnnotationPresent(MyAnnotation111.class)) {
                MyAnnotation111 annotation111 = field.getAnnotation(MyAnnotation111.class);
                //设置可以访问private属性
                field.setAccessible(true);
                // 设置属性的性别值为注释的值
                String value = annotation111.value();
                field.set(student, value);
            }
        }
        return student;
    }
}
4. 测试类StudentTest
public class StudentTest {
    //测试并获取类上的注释
    @Test
    public void test1(){

        MyAnnotation222 annotation222 = Student.class.getAnnotation(MyAnnotation222.class);
        System.out.println("stu_name = " + annotation222.stuName() + " id: " + annotation222.stuId());
    }

    //测试是否修改性别为注释默认值
    @Test
    public void test2() throws IllegalAccessException {
        Student student = new Student("李四", "20210635128634", "女");
        Student.modifyGender(student);
        System.out.println(student.toString());
    }
}

test1输出:
stu_name = 张三 id: 20240101023505

test2输出:
Student{stuName=‘李四’, stuId=‘20210635128634’, gender=人妖}

总结

大家可以模仿我的案例自行测试,最好亲手做一遍!!!
框架 = 注解 + 反射 + 设计模式(我们一定要掌握基本的注释类原理)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值