• 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
     

  • 相关阅读:
    03 Java 修饰符
    04_Java 循环结构 for, while 及 do...while
    01_Java第一个程序_报错记录
    07_Java StringBuffer 和 StringBuilder 类_(修改,并且不产生新的未使用对象)
    06_Math 的 floor,round 和 ceil 方法实例比较_格式化字符串_String类
    [爱偷懒的程序员系列]Section 1. “懒”是一切需求的根源
    (1)Micropython+ESP32 点亮一个LED
    数据迁移测试方法【转】
    回来了回来了,失踪人口回归
    [爱偷懒的程序员系列]Section 4. 自定义钉钉消息推送
  • 原文地址:https://www.cnblogs.com/zt007/p/10362141.html
Copyright © 2020-2023  润新知