Java 获取对象全部属性 包括 父类属性
今天由于业务需要,看一段数据库中的表转化成用户可以看懂的数据,也就是把一些字段比如Date用ms存的,转化为'yyyy-MM-dd'这种格式,但是由于字段太多,所以利用Java反射机制自带的BeanUtils相关的方法来进行转化(要求两个类的属性名称相同),当然这个方法只支持基本数据类型,如Long,Integer,String,Short之类的转化,但是像Date类型就需要自己手动判断来转,这就出现了今天所遇到的坑
先看下反射机制是如何获取类的方法的:
Class clazz = object.getClass();
clazz.getDeclaredFields();
clazz.getFields()
通过getClass()方法来获取类的定义信息,通过定义信息再调用getFields()方法来获取类的所有公共属性,或者调用getDeclaredFields()方法来获取类的所有属性,包括公共,保护,私有,默认的方法,但是这里有一点要注意的是这个方法只能获取当前类里面显示定义的属性,不能获取到父类或者父类的父类及更高层次的属性的,所以我们要想获取类的所有属性,还要获取父类的属性:
public static Field[] getAllFields(Object object){
Class clazz = object.getClass();
List<Field> fieldList = new ArrayList<>();
while (clazz != null){
fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
clazz = clazz.getSuperclass();
}
Field[] fields = new Field[fieldList.size()];
fieldList.toArray(fields);
return fields;
}
这个方法通过while循环及getSuperClass()方法获取当前类的父类再进行getDeclaredFields()即可,注意这个方法返回的是一个Field数组,然后如果我们想要把这些属性拼接到一起,当然是使用链表更方便一些,利用Arrays.asList()方法将数组转化为链表,注意:这个方法返回的是一个List<>也就是抽象列表,所以要将其再用ArrayList初始化一次得到的列表才可变,否则得到的是一个不可变的列表.
然后我们再利用列表的toArray()方法将列表转为数组,注意:这里又有一个坑,这个方法提供了两种实现:
Object[] toArray();
<T> T[] toArray(T[] a);
第一种无参,但注意,返回值类型为Object数组类型,直接这么写肯定会报错,但是如果强制转换为需要的类型,则在运行时会抛这样一个异常:
异常信息 程序会告诉你无法这么转换,所以这里要注意
第二种的参数就填你要转换的数组就可以,但是他要求数组的长度是等于链表的长度的,否则会编译不通过,所以得到链表之后在初始化数组即可
然后这里在测试时导师提到了一个点就是循环依赖的问题,担心while会跳不出来,但是这里其实跟属性的具体类型是无关的,所以不会出现这个问题,但是就顺便了解了下循环依赖的相关概念,比如我定义两个类:
class ClassA {
int a;
ClassB ab;
public ClassA(){
ab = new ClassB();
}
}
class ClassB extends ClassA {
int b;
ClassA ba; public ClassB() {
this.ba = new ClassA();
}
乍一眼看上去有很大问题嘛,怎么A是B的父类,A里面还有一个属性是B类的,其实这个问题跟继承关系也不大,只不过继承关系会让人印象更深刻,因为这段代码编译是可以通过的,那么我们来实例化一个B类看看会发生什么:
异常信息接下来基本都是这样的情况了,java抛出了栈溢出,从结果中也可以想出这个问题,即A的属性引用了B类,而B的属性又引用了A类,这使得在B类实例化时去初始化A,A又初始化B,就这么陷入了一个死循环,最终导致程序栈溢出,所以我们在实际编码过程中要千万注意这种情形,如果发生在业务中,则是巨大的隐患存在.
作者:xdlkc
链接:https://www.jianshu.com/p/6fe3e0e185ac
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
Java 获取对象全部属性 包括 父类属性的更多相关文章
- 【java】java获取对象属性类型、属性名称、属性值
java获取对象属性类型.属性名称.属性值 获取属性 修饰符:[在Field[]循环中使用] String modifier = Modifier.toString(fields[i].getModi ...
- java获取对象属性类型、属性名称、属性值
/** * 根据属性名获取属性值 * */ private Object getFieldValueByName(String fieldName, Object o) { try { String ...
- java获取对象属性类型、属性名称、属性值 【转】
/** * 根据属性名获取属性值 * */ private Object getFieldValueByName(String fieldName, Object o) { try { String ...
- java 获取对象的数据类型
// java 获取对象的数据类型 public static String getType(Object object){ String typeName=object.getClass().get ...
- Java获取项目根目录等其他系统属性
一 相对路径的获得 说明:相对路径(即不写明时候到底相对谁)均可通过以下方式获得(不论是一般的java项目还是web项目) String relativelyPath=System.getProper ...
- Java-Reflection反射-获取包括父类在内的所有字段
前言 今天Android移动端要加个新功能,所以回归Android程序员的身份.开发的过程中,发现了之前的代码写的有很多问题,真的应该把时间抽出来重构一下了. 其中有反射的一个坑,工具类某方法反射获取 ...
- Java反射获取对象成员属性,getFields()与getDeclaredFields()方法的区别
Java反射获取对象成员属性,getFields()与getDeclaredFields()方法的区别 在工作中遇到一个问题,就是你需要去判断某个字符串是不是对象的某个成员属性名,然后根据判断结果 ...
- 乐字节Java反射之二:实例化对象、接口与父类、修饰符和属性
大家好,小乐继续接着上集:乐字节Java反射之一:反射概念与获取反射源头Class 这次是之二:实例化对象.接口与父类.修饰符和属性 一:实例化对象 之前我们讲解过创建对象的方式,有new .克隆.反 ...
- Java反射获取对象VO的属性值(通过Getter方法)
有时候,需要动态获取对象的属性值. 比如,给你一个List,要你遍历这个List的对象的属性,而这个List里的对象并不固定.比如,这次User,下次可能是Company. e.g. 这次我需要做一个 ...
随机推荐
- Codechef August Challenge 2019 Division 2
Preface 老年菜鸡终于开始打CC了,由于他太弱了所以只能打Div2 因为台风的原因challenge并没有写,所以水了个Rank7 A Football SB模拟题不解释 #include< ...
- Spring Cloud Zuul记录接口响应数据
系统在生产环境出现问题时,排查问题最好的方式就是查看日志了,日志的记录尽量详细,这样你才能快速定位问题. 如果需要在Zuul中进行详细的日志记录,这两种日志必不可少. API请求信息 API响应信息 ...
- BeanCreationException: Error creating bean with name 'classPathFileSystemWatcher'之解决办法
错误关键信息: BeanCreationException: Error creating bean with name 'classPathFileSystemWatcher' 错误原因:Idea不 ...
- 第四次实验报告:使用Packet Tracer理解RIP路由协议
目录 1 实验目的 2 实验内容 3. 实验报告 3.1 建立网络拓扑结构 3.2 配置参数 3.3 测试网络连通性 3.4 理解RIP路由表建立和更新 4. 理解RIP消息传得慢 5. 拓展 1 实 ...
- R语言学习基础一
笔者使用Rstudio编写R程序,本文主要总结在编写过程中遇到的一些实际 问题 与学习配套的的code上传到我的github,网址: https://github.com/LIU-HONGYANG/S ...
- 通过IP获取MAC地址例子(应用层)
博客地址:http://home.cnblogs.com/u/zengjianrong/ 由于某种需求,需要获取某个ip的mac地址,在应用层实现例子如下代码. 流程:1. 先遍历arp表,若存在对应 ...
- c++小学期大作业攻略(一)环境配置
UPDATE at 2019/07/20 20:21 更新了Qt连接mysql的方法,但是是自己仿照连VS的方法摸索出来的,简单测试了一下能work但是不保证后期不会出问题.如果你在尝试过程中出现了任 ...
- 【转帖】分布式事务之解决方案(XA和2PC)
分布式事务之解决方案(XA和2PC) https://zhuanlan.zhihu.com/p/93459200 博彦信息技术有限公司 java工程师 3. 分布式事务解决方案之2PC(两阶段提交 ...
- Hash函数浅谈
Hash函数是指把一个大范围映射到一个小范围.把大范围映射到一个小范围的目的往往是为了节省空间,使得数据容易保存. 除此以外,Hash函数往往应用于查找上.所以,在考虑使用Hash函数之前,需要明白它 ...
- 极简 Spring Boot 整合 Thymeleaf 页面模板
虽然现在慢慢在流行前后端分离开发,但是据松哥所了解到的,还是有一些公司在做前后端不分的开发,而在前后端不分的开发中,我们就会需要后端页面模板(实际上,即使前后端分离,也会在一些场景下需要使用页面模板, ...

