本文已参与「新人创作礼」活动,一起开启掘金创作之路。
这篇文章我们来介绍,如何通过反射获取类的属性值,如何修改类的属性值。
我们依旧根据这篇文章中的类结构来完成下面内容的介绍。
获取并修改类中public 属性值
在上述类中,我们一共定了了三个属性值,一个static,一个public,一个private。
这里我们先介绍一下如何操作public 属性,如何获取并修改它。
Class<?> clazz = Student.class;
try {
Student student = new Student();
Field field = clazz.getField("age");
System.out.println("通过反射得到age: " + field.get(student));
student.age = 20;
System.out.println("通过反射得到age: " + field.get(student));
field.set(student, 30);
System.out.println(student.age);
} catch (Exception e) {
e.printStackTrace();
}
这里需要说明的是,调用clazz.getField 的时候,需要传入的参数应该是待处理的变量名,这个方法的返回值不是age属性(不是int age),也就是说,直接通过getField 方法是不能不能直接获取和修改值的。
获取并修改类中的private 属性
在Student 类中我们定义个private 属性是name。我们看一下如何获取并修改name。
Class<?> clazz = Student.class;
try{
Student student = new Student();
Field field = clazz.getDeclaredField("name");
field.setAccessible(true);
System.out.println("the data from reflection: " + field.get(student));
field.set(student, "Kite");
System.out.println(student.getName());
}
catch (Exception e){
e.printStackTrace();
}
对于获取私有属性,流程和获取public 属性差不多,只不过获取公有属性调用的方法时getField,但是获取私有属性方法的时候获取的是getDeclaredField。(注意:这个方法当然也可以用作获取public 属性)
获取并修改类中的静态属性
这里而我们依旧通过例子来看一下,如何获取类中的静态属性,并做修改。
Class<?> clazz = Student.class;
try{
Field field = clazz.getDeclaredField("maxAge");
field.setAccessible(true);
// 由于这里获取的是静态属性,在调用方法的时候就不需要传入特定的实例对象。
System.out.println("data from reflection: " + field.get(null));
field.set(null, 250);
System.out.println("data from reflection: " + field.get(null));
}
catch (Exception e){
e.printStackTrace();
}
这里需要注意的只有静态属性和非静态属性的区别,使用也不一样。在通过反射获取静态属性的时候,会调用field.get 方法,这个时候不需要传入实例化对象,只需要传入null 就可以了。
通过反射获取类中的所有属性
最后我们来看一下如何获取类中的所有属性。
Class<?> clazz = Student.class;
Field[] declaredFields = clazz.getDeclaredFields();
Student student = new Student();
for (Field declaredField : declaredFields){
try{
declaredField.setAccessible(true);
System.out.println("field is: " + declaredField.getName() + ", field name is: " + declaredField.getType().getName() + ", value is: " + declaredField.get(student));
}
catch (Exception e) {
e.printStackTrace();
}
}
这里对比上文,我们只有一个需要记忆的地方,就是clazz.getDeclaredFields(); 就可获取类中所有属性。
总结
这篇文章内容比较多,但是相对来说是比较好记忆以及理解的。主要介绍了如何通过反射获取类中的不同类型的变量,同时介绍了通过什么办法可以去修改这些值。读者理应好好理解并记忆一下。