zoukankan      html  css  js  c++  java
  • 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
     

  • 相关阅读:
    MSSQL 链接Oracle 表
    ORACLE FORM ZA 常用子程序
    FORM 中提交报表并查看结果
    Form界面设置只读
    FRM30403
    oracle 分区表的建立方法
    在Oracle Form中,如何实现自动编号(行号)的功能
    Form中格式化数字、金额
    MSC_SYSTEM_ITEMS,mtl_system_items_b区别
    C#中判断一个字符串是不是包含非法字符
  • 原文地址:https://www.cnblogs.com/zt007/p/10362141.html
Copyright © 2011-2022 走看看