反射是程序在运行时能够动态获取类对象的属性,调用类对象的方法。说白点:在程序运行状态中,任何一个类都能够知道这个类的属性和方法,类对应到对象,任何一个对象都能够调用它的方法和属性。如果比较喜欢看框架底层的逻辑,你会发现所有框架的底层,都离不开反射。
这边通过一个实例,先简单认识一下:通过反射获取当前对象的各个属性、属性类型、属性对应的值
1.构造一个对象,并给对象各个属性赋值
@Data
@Builder
public class Student {
private Long studentId;
private String studentName;
private Integer age;
private Double score;
private Date inSchoolTime;
}
2.通过对象的geClass方法获取反射对象,然后就可以获取到所有的成员变量Field,根据反射提供的API就可以获取到各个成员变量的属性了
public class ReflectDemo {
@Test
public void test1(){
Student student = getStudent();
//获取反射对象
Class<? extends Student> clazz = student.getClass();
//获取所有成员变量对象
Field[] fields = clazz.getDeclaredFields();
//遍历对象下的成员变量(属性)
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
//获取属性名
String name = field.getName();
//获取属性类型
Class<?> type = field.getType();
//获取属性值
try {
//设置属性的可访问性(只有设置这个之后才可以获取到value的值)
field.setAccessible(true);
Object value = field.get(student);
System.out.println("name: "+name+" ,type: "+type+" ,value: "+value);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
/**
* 构造对象
*/
private Student getStudent() {
Date date = null;
try {
date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2022-01-01 09:00:00");
} catch (ParseException e) {
e.printStackTrace();
}
Student student = Student.builder().studentId(129L).studentName("张某人").age(13)
.score(98.8).inSchoolTime(date).build();
return student;
}
}
打印结果:
name: studentId ,type: class java.lang.Long ,value: 129
name: studentName ,type: class java.lang.String ,value: 张某人
name: age ,type: class java.lang.Integer ,value: 13
name: score ,type: class java.lang.Double ,value: 98.8
name: inSchoolTime ,type: class java.util.Date ,value: Sat Jan 01 09:00:00 CST 2022
3.扩展:instanceof的用法(反射给各个变量归类,判断变量属于哪个类)
instanceof用于判断前面的对象是否属于后面的类,或者属于其子类。例如:大黄 instanceof 狗 / 大黄 instanceof 动物,这两个条件都是成立的,大黄这个对象,属于狗类,也属于动物大类
@Test
public void test1(){
Student student = getStudent();
//获取反射对象
Class<? extends Student> clazz = student.getClass();
//获取所有成员变量对象
Field[] fields = clazz.getDeclaredFields();
//遍历对象下的成员变量(属性)
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
//获取属性名
String name = field.getName();
//获取属性类型
Class<?> type = field.getType();
//获取属性值
try {
//设置属性的可访问性(只有设置这个之后才可以获取到value的值)
field.setAccessible(true);
Object value = field.get(student);
//判断前面的对象是否属于后面的类,或者属于其子类
if (value instanceof Date) {
System.out.println("date类型的值:" + value);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
打印结果:
date类型的值:Sat Jan 01 09:00:00 CST 2022
有兴趣的可以试试看,通过反射进行动态的创建对象和编译,不要总是拘泥于传统的CURD!