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

​ 在工作中遇到一个问题,就是你需要去判断某个字符串是不是对象的某个成员属性名,然后根据判断结果去操作这个成员属性。

想了下之后,我们可以根据Java反射中的getDeclaredFields()或者getFields()方法来实现我们的需求。

​ 首先说明一下getDeclaredFields()getFields()这两个方法的区别:

getFields(): 获取某个类的所有的public字段,其中是包括父类的public字段的。

getDeclaredFields():获取某个类的自身的所有字段,不包括父类的字段。

示例1:--子类、父类

 package com.test.test;

 import java.lang.reflect.Field;
import java.lang.reflect.Modifier; public class Demo {
/**
* Java反射获取对象成员属性,getFields()与getDeclaredFields()方法的区别
* --子类、父类
*
* @param args
* @throws IllegalAccessException
*/
public static void main(String[] args) throws IllegalAccessException { Person.Student student = new Person.Student();
student.setGrade(99);
student.setStudentNumber("20191223");
student.setName("张三");
student.setAge(22); System.out.println("======getFields()======");
Field[] fields = student.getClass().getFields();
for (Field field : fields) {
System.out.println("成员属性:" + field.getName() + " 成员属性修饰符: " + Modifier.toString(field.getModifiers()) + " 成员属性值: " + field.get(student));
} System.out.println("======getDeclaredFields()======");
Field[] declaredFields = student.getClass().getDeclaredFields();
for (Field field : declaredFields) {
// 获取原来的访问控制权限
boolean accessFlag = field.isAccessible();
if (!field.isAccessible()) field.setAccessible(true);
System.out.println("成员属性:" + field.getName() + " 成员属性修饰符: " + Modifier.toString(field.getModifiers()) + " 成员属性值: " + field.get(student));
field.setAccessible(accessFlag);
}
}
}

示例1--子类、父类

示例1结果:

 ======getFields()======
成员属性:studentNumber 成员属性修饰符: public 成员属性值: 20191223
成员属性:name 成员属性修饰符: public 成员属性值: 张三
======getDeclaredFields()======
成员属性:studentNumber 成员属性修饰符: public 成员属性值: 20191223
成员属性: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:--静态内部类

 package com.test.test;

 import java.lang.reflect.Field;
import java.lang.reflect.Modifier; public class Demo2 {
/**
* Java反射获取对象成员属性,getFields()与getDeclaredFields()方法的区别
* --静态内部类
*
* @param args
* @throws IllegalAccessException
*/
public static void main(String[] args) throws IllegalAccessException { StudentInfo studentInfo = new StudentInfo();
studentInfo.setName("张三");
StudentInfo.StudyInfo studyInfo = new StudentInfo.StudyInfo("语文", "99");
studentInfo.setStudyInfo(studyInfo);
System.out.println("studentInfo = " + studentInfo); System.out.println("======getFields()======");
Field[] fields = studentInfo.getClass().getFields();
for (Field field : fields) {
System.out.println("成员属性:" + field.getName() + " 成员属性修饰符: " + Modifier.toString(field.getModifiers()) + " 成员属性值: " + field.get(studentInfo));
} System.out.println("======getDeclaredFields()======");
Field[] declaredFields = studentInfo.getClass().getDeclaredFields();
for (Field field : declaredFields) {
// 获取原来的访问控制权限
boolean accessFlag = field.isAccessible();
if (!field.isAccessible()) field.setAccessible(true);
System.out.println("成员属性:" + field.getName() + " 成员属性修饰符: " + Modifier.toString(field.getModifiers()) + " 成员属性值: " + field.get(studentInfo));
field.setAccessible(accessFlag);
}
}
}

示例2--静态内部类

示例2结果:

 studentInfo = PwdFiled{name='张三', studyInfo=StudyInfo{subjectName='语文', score='99'}}
======getFields()======
成员属性:name 成员属性修饰符: public 成员属性值: 张三
======getDeclaredFields()======
成员属性:name 成员属性修饰符: public 成员属性值: 张三
成员属性:studyInfo 成员属性修饰符: private 成员属性值: StudyInfo{subjectName='语文', score='99'}

示例2结果

从结果可以看到
1.使用getFields()方法
fields数组中只包含了public修饰的成员属性。 2.使用getDeclaredField()方法
fields数组中只包含了类StudentInfo的所有成员属性

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

Java反射获取对象成员属性,getFields()与getDeclaredFields()方法的区别的更多相关文章

  1. Java反射获取对象VO的属性值(通过Getter方法)

    有时候,需要动态获取对象的属性值. 比如,给你一个List,要你遍历这个List的对象的属性,而这个List里的对象并不固定.比如,这次User,下次可能是Company. e.g. 这次我需要做一个 ...

  2. java反射获取字段的属性值,以及为字段赋值等方法

    1.获取某个类的属性值 /*利用getter方法获取值(首字母大写) CjJssetDTO obj: */ String filedName = "Cj"+(i+1); Class ...

  3. java反射获取Object的属性和值

    在看反射顺便做个笔记,目前知道的反射的Object都是要有对象的也就是实体Bean. import java.lang.reflect.Field; import java.util.ArrayLis ...

  4. 第五课 JAVA反射获取对象属性和方法(通过配置文件)

    Service1.java package reflection; public class Service1 { public void doService1(){ System.out.print ...

  5. 第五课 JAVA反射获取对象属性和方法

    package com.hero; import java.lang.reflect.Field; public class TestReflction5 { public static void m ...

  6. java 反射获取类的属性 类型 名称和值

    /** * 获取属性类型(type),属性名(name),属性值(value)的map组成的list * */ private List getFiledsInfo(Object o){ Field[ ...

  7. 【java】java反射机制,动态获取对象的属性和对应的参数值,并属性按照字典序排序,Field.setAccessible()方法的说明【可用于微信支付 签名生成】

    方法1:通过get()方法获取属性值 package com.sxd.test.controller; public class FirstCa{ private Integer num; priva ...

  8. Java 获取对象全部属性 包括 父类属性

    今天由于业务需要,看一段数据库中的表转化成用户可以看懂的数据,也就是把一些字段比如Date用ms存的,转化为'yyyy-MM-dd'这种格式,但是由于字段太多,所以利用Java反射机制自带的BeanU ...

  9. Java反射学习-1 - 反射获取类的属性,方法,构造器

    新建一个Person类 package cn.tx.reflect; /** * 注解初步了解 * @author Administrator * */ public class Person { p ...

随机推荐

  1. 最近公共祖先LCA Tarjan 离线算法

    [简介] 解决LCA问题的Tarjan算法利用并查集在一次DFS(深度优先遍历)中完成所有询问.换句话说,要所有询问都读入后才开始计算,所以是一种离线的算法. [原理] 先来看这样一个性质:当两个节点 ...

  2. mysql系列-安装及服务启动

    一.window下的安装 详细见官网 https://dev.mysql.com/doc/refman/5.7/en/windows-installation.html 以 MySQL 5.1 免安装 ...

  3. 初试百度地图API

    第一次使用百度地图API来定位并显示,参照了官网2.1.0版本demo里的DemoApplication和LocationOverlayDemo两个类来写,整了半天显示一片空白(图一),然后郁闷了半天 ...

  4. 数据库读写锁的实现(C++)

    一.基本概念 在数据库中,对某数据的两个基本操作为写和读.分布有两种锁控制:排它锁(X锁).共享锁(S锁). 排它锁(x锁):若事务T对数据D加X锁,则其他不论什么事务都不能再对D加不论什么类型的锁. ...

  5. python良好的编程习惯

    良好的编程习惯 2.1 在程序中是用丰富的注释,注释有助于其他程序员理解程序,有助于程序调试(发现和排除程序中的错误),并列出有用的信息.以后修改或更新代码时,注释还有助于理解当初自己编写的程序 2. ...

  6. Http协议三次握手过程

    Http协议三次握手过程   TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: ...

  7. MongoDB系列四:解决secondary的读操作

    http://blog.itpub.net/26812308/viewspace-2124660/ 在Replica sets 中的secondary节点默认是不可读的.使用Replica Sets实 ...

  8. 微信小程序 之 请求函数封装

    封装的request的代码 /** * @desc API请求接口类封装 */ /** * POST请求API * @param {String} url 接口地址 * @param {Object} ...

  9. STL学习笔记(迭代器相关辅助函数)

    advance()可令迭代器前进 #include <iterator> void advance(InputIterator& pos,Dist n); 面对Random Acc ...

  10. 【Excle数据透视表】如何按照地区交替填充背景颜色

    现存在如下数据透视表 需要根据地区填充不同的背景颜色 步骤 选定数值区域→开始→条件格式→新建规则,出现如下窗口: 公式:=MOD(COUNT(1/(MATCH($A$4:$A4,$A$4:$A4,) ...