Java反射获取对象成员属性,getFields()与getDeclaredFields()方法的区别
在工作中遇到一个问题,就是你需要去判断某个字符串是不是对象的某个成员属性名,然后根据判断结果去操作这个成员属性。
想了下之后,我们可以根据Java反射中的getDeclaredFields()或者getFields()方法来实现我们的需求。
首先说明一下getDeclaredFields()和getFields()这两个方法的区别:
getFields(): 获取某个类的所有的public字段,其中是包括父类的public字段的。
getDeclaredFields():获取某个类的自身的所有字段,不包括父类的字段。
示例1:--子类、父类
1 package com.test.test; 2 3 import java.lang.reflect.Field; 4 import java.lang.reflect.Modifier; 5 6 public class Demo { 7 /** 8 * Java反射获取对象成员属性,getFields()与getDeclaredFields()方法的区别 9 * --子类、父类 10 * 11 * @param args 12 * @throws IllegalAccessException 13 */ 14 public static void main(String[] args) throws IllegalAccessException { 15 16 Person.Student student = new Person.Student(); 17 student.setGrade(99); 18 student.setStudentNumber("20191223"); 19 student.setName("张三"); 20 student.setAge(22); 21 22 System.out.println("======getFields()======"); 23 Field[] fields = student.getClass().getFields(); 24 for (Field field : fields) { 25 System.out.println("成员属性:" + field.getName() + " 成员属性修饰符: " + Modifier.toString(field.getModifiers()) + " 成员属性值: " + field.get(student)); 26 } 27 28 System.out.println("======getDeclaredFields()======"); 29 Field[] declaredFields = student.getClass().getDeclaredFields(); 30 for (Field field : declaredFields) { 31 // 获取原来的访问控制权限 32 boolean accessFlag = field.isAccessible(); 33 if (!field.isAccessible()) field.setAccessible(true); 34 System.out.println("成员属性:" + field.getName() + " 成员属性修饰符: " + Modifier.toString(field.getModifiers()) + " 成员属性值: " + field.get(student)); 35 field.setAccessible(accessFlag); 36 } 37 } 38 }
示例1结果:
1 ======getFields()====== 2 成员属性:studentNumber 成员属性修饰符: public 成员属性值: 20191223 3 成员属性:name 成员属性修饰符: public 成员属性值: 张三 4 ======getDeclaredFields()====== 5 成员属性:studentNumber 成员属性修饰符: public 成员属性值: 20191223 6 成员属性:grade 成员属性修饰符: private 成员属性值: 99.0
从结果可以看到
1.使用getFields()方法
fields数组中只包含了public修饰的成员属性,其中除了子类本身的public类型属性,也包括了父类的public类型属性。
2.使用getDeclaredField()方法报错:
Exception in thread "main" java.lang.IllegalAccessException: Class com.test.test.Demo can not access a member of class com.test.test.Person$Student with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
==>对于私有的成员变量来说,要操作其属性值的话,就需要设置setAccessible(true);
field.setAccessible(true)就是让我们在反射时可以操作私有成员属性的值。
结果:fields数组中只包含了子类Student的所有成员属性,不包含父类任何类型的成员属性
示例2:--静态内部类
1 package com.test.test; 2 3 import java.lang.reflect.Field; 4 import java.lang.reflect.Modifier; 5 6 public class Demo2 { 7 /** 8 * Java反射获取对象成员属性,getFields()与getDeclaredFields()方法的区别 9 * --静态内部类 10 * 11 * @param args 12 * @throws IllegalAccessException 13 */ 14 public static void main(String[] args) throws IllegalAccessException { 15 16 StudentInfo studentInfo = new StudentInfo(); 17 studentInfo.setName("张三"); 18 StudentInfo.StudyInfo studyInfo = new StudentInfo.StudyInfo("语文", "99"); 19 studentInfo.setStudyInfo(studyInfo); 20 System.out.println("studentInfo = " + studentInfo); 21 22 System.out.println("======getFields()======"); 23 Field[] fields = studentInfo.getClass().getFields(); 24 for (Field field : fields) { 25 System.out.println("成员属性:" + field.getName() + " 成员属性修饰符: " + Modifier.toString(field.getModifiers()) + " 成员属性值: " + field.get(studentInfo)); 26 } 27 28 System.out.println("======getDeclaredFields()======"); 29 Field[] declaredFields = studentInfo.getClass().getDeclaredFields(); 30 for (Field field : declaredFields) { 31 // 获取原来的访问控制权限 32 boolean accessFlag = field.isAccessible(); 33 if (!field.isAccessible()) field.setAccessible(true); 34 System.out.println("成员属性:" + field.getName() + " 成员属性修饰符: " + Modifier.toString(field.getModifiers()) + " 成员属性值: " + field.get(studentInfo)); 35 field.setAccessible(accessFlag); 36 } 37 } 38 }
示例2结果:
1 studentInfo = PwdFiled{name='张三', studyInfo=StudyInfo{subjectName='语文', score='99'}} 2 ======getFields()====== 3 成员属性:name 成员属性修饰符: public 成员属性值: 张三 4 ======getDeclaredFields()====== 5 成员属性:name 成员属性修饰符: public 成员属性值: 张三 6 成员属性:studyInfo 成员属性修饰符: private 成员属性值: StudyInfo{subjectName='语文', score='99'}
从结果可以看到 1.使用getFields()方法 fields数组中只包含了public修饰的成员属性。 2.使用getDeclaredField()方法 fields数组中只包含了类StudentInfo的所有成员属性
转自:https://blog.csdn.net/liujun03/article/details/81512834