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. 【bzoj1226】【[SDOI2009]学校食堂Dining】状压dp

    (上不了p站我要死了,侵权度娘背锅) Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人 ...

  2. iOS 耳机线控

    当你使用iphone的时候听音乐的时候,播放器在后台运行的时候,你仍然可以通过耳机来进行操作,完成曲目切换,快进,快退等功能!当然你的程序不一定是播放器应用,但是我们仍然可以让它具有这个功能,让用户通 ...

  3. 随机取若干条记录的SQL语句

    原文:随机取若干条记录的SQL语句 MySql中随机提取数据库N条记录 select * from TableName order by rand() limit N   SQLServer中随机提取 ...

  4. linux之网络配置相关

    ubuntu的网络配置文件在 /etc/network/intrfaces; suse的网络配置在          /etc/sysconfig/network/下面,每个网卡一个配置文件. int ...

  5. linux之ifconfig命令

    1.命令格式: ifconfig [网络设备] [参数] 2.命令功能: ifconfig 命令用来查看和配置网络设备.当网络环境发生改变时可通过此命令对网络进行相应的配置. 3.命令参数: up 启 ...

  6. Android - toolbar navigation 样式

    1.修改title 边距 修改边距使用系统的app属性来引入使用,即: xmlns:app="http://schemas.android.com/apk/res-auto" 1 ...

  7. vue的表单的简单介绍 input radio checkbox等表单特性

    在vue中我们可以通过v-model来为表单元素实现双向绑定 1:v-model指令 数据的双向绑定 双向绑定是说我们不仅仅可以通过数据(M)的改变去影响视图(V),还是当视图的内容改变(V)去影响模 ...

  8. Architecting Android…The clean way?

    Architecting Android-The clean way? 原文链接:http://fernandocejas.com/2014/09/03/architecting-android-th ...

  9. django book表单验证学习

    django提供了强大的表单验证功能form 个人认为是把html代码封装到form里面,就像封装models中的数据一样.而且带有强大的验证功能,不需要后台再去写一堆乱七八糟的验证 具体操作查看dj ...

  10. How to support both ipv4 and ipv6 address for JAVA code.

    IPv6 have colon character, for example FF:00::EEIf concatenate URL String, IPv6 URL will like: http: ...