示例代码:
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();
}
}
}
按照上述代码执行结果
赋值失败原因:
反射是一种运行时操作类的技术
上述代码中注解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();
}