Java 獲取對象所有屬性 包括 父類屬性

  • 今天因爲業務須要,看一段數據庫中的錶轉化成用戶能夠看懂的數據,也就是把一些字段好比Date用ms存的,轉化爲'yyyy-MM-dd'這種格式,可是因爲字段太多,因此利用Java反射機制自帶的BeanUtils相關的方法來進行轉化(要求兩個類的屬性名稱相同),固然這個方法只支持基本數據類型,如Long,Integer,String,Short之類的轉化,可是像Date類型就須要本身手動判斷來轉,這就出現了今天所遇到的坑java

  • 先看下反射機制是如何獲取類的方法的:數據庫

    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()方法將列表轉爲數組,注意:這裏又有一個坑,這個方法提供了兩種實現:this

    Object[] toArray();
    <T> T[] toArray(T[] a);

    ​ 第一種無參,但注意,返回值類型爲Object數組類型,直接這麼寫確定會報錯,可是若是強制轉換爲須要的類型,則在運行時會拋這樣一個異常:編碼

     
    異常信息

    ​ 程序會告訴你沒法這麼轉換,因此這裏要注意spa

    ​ 第二種的參數就填你要轉換的數組就能夠,可是他要求數組的長度是等於鏈表的長度的,不然會編譯不經過,因此獲得鏈表以後在初始化數組便可code

  • 而後這裏在測試時導師提到了一個點就是循環依賴的問題,擔憂while會跳不出來,可是這裏其實跟屬性的具體類型是無關的,因此不會出現這個問題,可是就順便了解了下循環依賴的相關概念,好比我定義兩個類:orm

    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 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。