前言

今天Android移动端要加个新功能,所以回归Android程序员的身份.开发的过程中,发现了之前的代码写的有很多问题,真的应该把时间抽出来重构一下了.

其中有反射的一个坑,工具类某方法反射获取传入Model的属性值.但是当我把公共属性抽出来做基类的时候,发现获取不到基类的属性值了.原因是使用了getDeclaredFields();

分析

方法 功能
getFields() 获取所有public字段,包括父类字段
getDeclaredFields() 获取所有字段,public和protected和private,但是不包括父类字段

写个小方法验证一下下~

写两个类,里面定义三个字段,分别用public,protected,private修饰, 
一个叫ParentModel,作为父类. 
一个叫model,继承ParentModel

/**
* 用作父类
*/
public class ParentModel { private String p_privateField;
public String p_publicField;
protected String p_protectedField;
}
/**
* 子类,继承上面定义的用作父类的ParentModel
*/
public class Model extends ParentModel{ private String privateField;
public String publicField;
protected String protectedField; }

ok,分别使用getFields()和getDeclaredFields()获取model的字段,循环打印出来.

 Field[] fs = Model.class.getFields();
Field[] fs1 = Model.class.getDeclaredFields();
for (Field f:fs) {
Log.d("getFields","getFields---"+f.getName());
} for (Field f:fs1) {
Log.d("getDeclaredFields","getDeclaredFields---"+f.getName());
}

见证答案的时候到了~ 
getFields()的打印输出:

getDeclaredFields()的打印输出:

测试证实了我们上面的结论是对的.

我想获取子类和父类的所有Field

如果想用反射通过Model获取parentModel和Model的所有字段,怎么办?很明显上面的两个方法都是满足不了的.那怎么办?

不用怕,我们递归Model的父类去getDeclaredFields(),代码如下:

List<Field> fieldList = new ArrayList<>() ;
Class tempClass = Model.class;
while (tempClass != null) {//当父类为null的时候说明到达了最上层的父类(Object类).
fieldList.addAll(Arrays.asList(tempClass .getDeclaredFields()));
tempClass = tempClass.getSuperclass(); //得到父类,然后赋给自己
}
for (Field f : fieldList) { Log.d("getAllFields","getFields---"+f.getName());
}

可以看到我们获取了Model和ParentModel的全部字段,不仅如此,还多出来了两个字段shadow$_klass_ 和shadow_monitor_,这个是Object中的字段.

shadow$_monitor_shadow$_klass_是Android sdk21之后Object增加的两个字段。

如果你想屏蔽Object类的影响,可以为while循环再添加一个条件:

while (tmpClass !=null && !tmpClass.getName().toLowerCase().equals("java.lang.object") )
{
....
}

更新说明

2017.6.27更新:

之前被网友 lucky_god88 指出博客反射获取的值和真实情况不符,核实之后,已经更正为正确答案,这里谢谢可爱的lucky_god88 发现并给我指出问题,解决问题的同时自己也在成长。同时也反省自己,以后要代码多加验证,谨慎细致,认真负责。

问题: 
1.getFields() 获取到 protected 类型字段的值

这个原因至今没有再次重现,很奇怪,很费解

2.getFields() 和 getDeclaredFields() 方法反射获取多了一个字段$change

这个和开发工具的配置有关系,好像是因为开启了Instant run 造成的,而且Android Studio 2.2.3已经修复了,链接在这里

Java-Reflection反射-获取包括父类在内的所有字段的更多相关文章

  1. java利用反射获取类的属性及类型

    java利用反射获取类的属性及类型. import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.Map ...

  2. java利用反射获取对象前后修改的内容(用于日志记录)

    import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Metho ...

  3. java 通过反射获取类属性结构,类方法,类父类及其泛型,类,接口和包

    首先自定义三个类 package reflection1; public interface MtInterface { void info(); } package reflection1; imp ...

  4. Java Reflection 反射基础

    反射基础: package reflection; /** * Created by : Infaraway * DATE : 2017/3/2 * Time : 23:06 * Funtion : ...

  5. java通过反射获取私有的构造方法,及反射擦除泛型数据类型约束

    /* * 反射获取私有的构造方法运行 * 不推荐,破坏了程序的安全性,封装性 * 暴力私有 */ public class ReflectDemo4 { public static void main ...

  6. java 通过反射获取调用类方法及属性

    首先说下反射是什么?反射是Sun公司推出的一组API,此组API位于Java.lang.reflect中 反射的作用是编写工具(例如eclipse),编写框架,当然对于一般的程序,我们不可能用反射来做 ...

  7. java通过反射获取调用变量以及方法

    一:反射概念 可以通过Class类获取某个类的成员变量以及方法,并且调用之. 二:通过反射获取方法.变量.构造方法 @Test // 通过反射获取类定义的方法 public void testMeth ...

  8. java通过反射获取Java对象属性值

    说明: 作为反射工具类,通过对象和属性的名字获取对象属性的值,如果在当前对象属性没有找到,依次向上收集所有父类的属 性,直到找到属性值,没有找到返回null: 代码: 1.classUtil pack ...

  9. java通过反射获取字段的类型

    import java.lang.reflect.Field;  //这是需要引入的包 Field[] f = 类名.class.getDeclaredFields(); //获取该类的字段for(F ...

随机推荐

  1. 周鸿祎与85后的座谈(一):人人需要Mentor,世界没有奇迹

    我们公司现在有将近 4000 人,我觉得里面肯定是卧虎藏龙.百里挑一的话,也有 40 个伟大的人才.但是,即使是天才,如果没有前辈的帮助,最后也会变成庸才,是做不出什么大事的.举例来说,每一个跳水冠军 ...

  2. 20155326刘美岑2016-2017-2《Java程序设计》第一周学习总结

    20155326刘美岑 2006-2007-2 <Java程序设计>第1周学习总结 教材学习内容总结 在老师的要求下我看了这门课的考察方式.这门课和以前上的课有些差别,成绩是由平时一点一点 ...

  3. android 增量更新原理

    原理如下:服务器端设计增量表,记录数据操作顺序id,和增删改查信息.在进行数据库表操作的时候同时进行将信息保存在增量表. android客户端在请求的时候上传最后保存的id.服务端判断最后的id,返回 ...

  4. js-设置时间,获取几天后的时间

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  5. CRC校验3种算法_转载

    //CRC16校验在通讯中应用广泛,这里不对其理论进行讨论,只对常见的3种//实现方法进行测试.方法1选用了一种常见的查表方法,类似的还有512字//节.256字等查找表的,至于查找表的生成,这里也略 ...

  6. 由异常掉电问题---谈xfs文件系统

    由异常掉电问题---谈xfs文件系统 本文皆是作者自己的学习总结或感悟(linux环境),如有不对,欢迎提出一起探讨!! 目录结构 一.相关知识 二.问题提出 三.处理方法 四.最终结果 一.相关知识 ...

  7. I2S接口工作原理

    I2S音频通信协议 I2S有3个主要信号: 1.串行时钟SCLK,也叫位时钟(BCLK),即对应数字音频的每一位数据,SCLK都有1个脉冲.SCLK的频率=2×采样频率×采样位数  2. 帧时钟LRC ...

  8. 火狐浏览器(Firefox)打开EBS form的设置方法

    http://yedward.net/?id=247 客户在使用EBS的时候,很多都是使用IE浏览器打开,但是EBS并不仅仅只是支持IE,对于谷歌浏览器(Chrome).火狐浏览器(Firefox)也 ...

  9. 阿里云oss服务通用类

    在webconfig中配置信息 <?xml version="1.0" encoding="utf-8"?><configuration> ...

  10. 关于ubuntu软件卸载的问题

    ...... 起因很菜....就是手贱把/usr/lib/下的R的目录给rm -rf掉了, 然后在R的软件包里用./configure也生不成, R RHOME还在, 然而因为lib下的R删掉了所以R ...