通过反射 + 注解给成员变量赋值失败

示例代码:

Entity注解

public @interface Entity {
    String value();
}

Student类

public class Student {

    @Entity("张三")
    private String name;//姓名

    @Entity("18")
    private int age;//年龄

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

测试类StuTest

public class StuTest {
    public static void main(String[] args) {
        try {
            //1、获取Student类的Class对象
            Class<?> stuClass = Class.forName("pojo.Student");
            //2、获取Field对象
            Field nameField = stuClass.getDeclaredField("name");
            Field ageField = stuClass.getDeclaredField("age");
            //暴力反射
            nameField.setAccessible(true);
            ageField.setAccessible(true);
            //通过反射创建Student对象
            Student stu = (Student) stuClass.newInstance();

            //判断成员变量是否有Entity注解
            boolean isTrue = nameField.isAnnotationPresent(Entity.class);

            if (isTrue){
                //获取Entity注解对象
                Entity nameAnno = nameField.getAnnotation(Entity.class);
                //将注解value属性值赋给stu对象name变量
                nameField.set(stu,nameAnno.value());
            }
            if (ageField.isAnnotationPresent(Entity.class)){
                Entity ageAnno = ageField.getAnnotation(Entity.class);
                ageField.set(stu,Integer.parseInt(ageAnno.value()));
            }

            System.out.println(stu);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

按照上述代码执行结果

image-20230219103917735

赋值失败原因:

反射是一种运行时操作类的技术

上述代码中注解Entity并未指定生命周期

@Retention

  • 作用:定义该注解的生命周期(有效范围)。

  • @Retention可选的参数值在枚举类型RetentionPolicy 中包括:

    • SOURCE:注解只存在于Java源代码中,编译生成的字节码文件中就不存在了

      • 使用场景:针对一些检查性的操作,比如:@Override ,就使用SOURCE注解
    • CLASS:注解存在于Java源代码、编译以后的字节码文件中,运行的时候内存中没有,默认值

      • 使用场景:在编译时进行一些预处理操作,比如:生成一些辅助代码,就用CLASS注解
    • RUNTIME:注解存在于Java源代码中、编译以后的字节码文件中、运行时内存中,程序可以通过反射获取该注解

      • 使用场景:要在运行时去动态获取注解信息,那只能用 RUNTIME 注解

解决办法:

给Entity注解加上@Retention(RetentionPolicy.RUNTIME)元注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Entity {
    String value();
}

image-20230219103848632

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值