• 今天由于业务需要,看一段数据库中的表转化成用户可以看懂的数据,也就是把一些字段比如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 获取对象全部属性 包括 父类属性的更多相关文章

  1. 【java】java获取对象属性类型、属性名称、属性值

    java获取对象属性类型.属性名称.属性值 获取属性 修饰符:[在Field[]循环中使用] String modifier = Modifier.toString(fields[i].getModi ...

  2. java获取对象属性类型、属性名称、属性值

    /** * 根据属性名获取属性值 * */ private Object getFieldValueByName(String fieldName, Object o) { try { String ...

  3. java获取对象属性类型、属性名称、属性值 【转】

    /** * 根据属性名获取属性值 * */ private Object getFieldValueByName(String fieldName, Object o) { try { String ...

  4. java 获取对象的数据类型

    // java 获取对象的数据类型 public static String getType(Object object){ String typeName=object.getClass().get ...

  5. Java获取项目根目录等其他系统属性

    一 相对路径的获得 说明:相对路径(即不写明时候到底相对谁)均可通过以下方式获得(不论是一般的java项目还是web项目) String relativelyPath=System.getProper ...

  6. Java-Reflection反射-获取包括父类在内的所有字段

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

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

    Java反射获取对象成员属性,getFields()与getDeclaredFields()方法的区别 ​ 在工作中遇到一个问题,就是你需要去判断某个字符串是不是对象的某个成员属性名,然后根据判断结果 ...

  8. 乐字节Java反射之二:实例化对象、接口与父类、修饰符和属性

    大家好,小乐继续接着上集:乐字节Java反射之一:反射概念与获取反射源头Class 这次是之二:实例化对象.接口与父类.修饰符和属性 一:实例化对象 之前我们讲解过创建对象的方式,有new .克隆.反 ...

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

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

随机推荐

  1. CSS中@support的用法 及其calc、media用法

    背景: 一次偶然的机会遇到一个朋友在刷css的库其中有这样一道题(css变量如何定义,calc, support, media),我看一眼熟悉而陌生,知其一而不知其二,叔可忍婶不可忍,马上就度娘起来, ...

  2. [LeetCode] 363. Max Sum of Rectangle No Larger Than K 最大矩阵和不超过K

    Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix s ...

  3. python与rpc服务

    什么是rpc 随着企业 IT 服务的不断发展,单台服务器逐渐无法承受用户日益增长的请求压力时,就需要多台服务器联合起来构成「服务集群」共同对外提供服务. 同时业务服务会随着产品需求的增多越来越肿,架构 ...

  4. 吉特仓储管理系统-ERP或WMS系统中常见术语

    MPS---主生产计划(Master Production schedules) MTO---订货生产(Make-to-Order) BOM---物料清单或产品结构表(Bill of material ...

  5. vue子组件数据跟着父组件改变

    父组件的代码 <template> <div class="home"> <img alt="Vue logo" src=&quo ...

  6. SQL语句中使用回车换行符

    今天发现sql数据库有个图片路径中包含空格,结果在替换和查找时,发现用空格无效,后来经过确认才发现原来是回车换行符引起,从表面看很像空格,实际是回车符,要用char(13)才能进行替换和查找 --查找 ...

  7. lombok的使用以及其中的坑

    1.lombok踩坑与思考 https://www.cnblogs.com/heyonggang/p/8638374.html 2.Lombok介绍.使用方法和总结 https://www.cnblo ...

  8. 折腾linux随笔 之 关闭Budgie默认自动隐藏应用的菜单栏 与 Gnome系桌面应用菜单无内容解决

    关闭Budgie默认自动隐藏应用菜单栏 首选项 -> 设置 -> 通用辅助功能 -> 打开 始终显示通用辅助菜单 后的开关 -> 注销桌面重新登录. done. 解决Gnome ...

  9. JavaScriptCore在浏览器引擎中的位置

    因为随着JS这门语言的发展,JS的宿主越来越多,有各种各样的浏览器,甚至是常见于服务端的Node.js(基于V8运行). 2.       Webkit 源代码由三大模块组成: 1). WebCore ...

  10. SQL IN 一定走索引吗?

    摘要 IN 一定走索引吗?那当然了,不走索引还能全部扫描吗?好像之前有看到过什么Exist,IN走不走索引的讨论.但是好像看的太久了,又忘记了.哈哈,如果你也忘记了MySQL中IN是如何查询的,就来复 ...