Java反射获取对象成员属性,getFields()与getDeclaredFields()方法的区别

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结果:

1 ======getFields()======
2 成员属性:studentNumber 成员属性修饰符: public 成员属性值: 20191223
3 成员属性:name 成员属性修饰符: public 成员属性值: 张三
4 ======getDeclaredFields()======
5 成员属性:studentNumber 成员属性修饰符: public 成员属性值: 20191223
6 成员属性:grade 成员属性修饰符: private 成员属性值: 99.0
示例1结果
从结果可以看到
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--静态内部类

示例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'}
示例2结果
从结果可以看到
1.使用getFields()方法
fields数组中只包含了public修饰的成员属性。

2.使用getDeclaredField()方法
fields数组中只包含了类StudentInfo的所有成员属性 

转自:https://blog.csdn.net/liujun03/article/details/81512834
 

原文地址:https://www.cnblogs.com/zt007/p/10362141.html