Java反射機制獲取父類屬性

  • 今天由于業(yè)務需要,看一段數(shù)據(jù)庫中的表轉化成用戶可以看懂的數(shù)據(jù),也就是把一些字段比如Date用ms存的,轉化為'yyyy-MM-dd'這種格式,但是由于字段太多,所以利用Java反射機制自帶的BeanUtils相關的方法來進行轉化(要求兩個類的屬性名稱相同),當然這個方法只支持基本數(shù)據(jù)類型,如Long,Integer,String,Short之類的轉化,但是像Date類型就需要自己手動判斷來轉,這就出現(xiàn)了今天所遇到的坑

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

    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循環(huán)及getSuperClass()方法獲取當前類的父類再進行getDeclaredFields()即可,注意這個方法返回的是一個Field數(shù)組,然后如果我們想要把這些屬性拼接到一起,當然是使用鏈表更方便一些,利用Arrays.asList()方法將數(shù)組轉化為鏈表,注意:這個方法返回的是一個List<>也就是抽象列表,所以要將其再用ArrayList初始化一次得到的列表才可變,否則得到的是一個不可變的列表.

    ? 然后我們再利用列表的toArray()方法將列表轉為數(shù)組,注意:這里又有一個坑,這個方法提供了兩種實現(xiàn):

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

    ? 第一種無參,但注意,返回值類型為Object數(shù)組類型,直接這么寫肯定會報錯,但是如果強制轉換為需要的類型,則在運行時會拋這樣一個異常:

    異常信息

    ? 程序會告訴你無法這么轉換,所以這里要注意

    ? 第二種的參數(shù)就填你要轉換的數(shù)組就可以,但是他要求數(shù)組的長度是等于鏈表的長度的,否則會編譯不通過,所以得到鏈表之后在初始化數(shù)組即可

  • 然后這里在測試時導師提到了一個點就是循環(huán)依賴的問題,擔心while會跳不出來,但是這里其實跟屬性的具體類型是無關的,所以不會出現(xiàn)這個問題,但是就順便了解了下循環(huán)依賴的相關概念,比如我定義兩個類:

    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類看看會發(fā)生什么:

    異常信息

    接下來基本都是這樣的情況了,java拋出了棧溢出,從結果中也可以想出這個問題,即A的屬性引用了B類,而B的屬性又引用了A類,這使得在B類實例化時去初始化A,A又初始化B,就這么陷入了一個死循環(huán),最終導致程序棧溢出,所以我們在實際編碼過程中要千萬注意這種情形,如果發(fā)生在業(yè)務中,則是巨大的隱患存在.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 一、注意點 面向對象的世界中,萬事萬物皆對象。 Java中的類,是java.util.Class類的實例對象 類的...
    androidjp閱讀 2,532評論 0 9
  • 一:java概述:1,JDK:Java Development Kit,java的開發(fā)和運行環(huán)境,java的開發(fā)工...
    ZaneInTheSun閱讀 2,813評論 0 11
  • “看!人造太陽!”不知是誰喊了一聲。大家定睛一看,原來飛碟已經隨著海水進入到了玻璃球殼罐內的最里層,透過海水和玻璃...
    渾水炊煙閱讀 325評論 0 2
  • 前言 隨手打開一個電商網站(如淘寶),查看商品的時候, 把鼠標放到圖片上都可以看到圖片的更多細節(jié),像把圖片局部放大...
    jazenye閱讀 1,632評論 0 10
  • 極簡主義是一種健康的生活方式和簡單的生活態(tài)度,是一種健康的心態(tài),是一種段舍離的智慧,是一種悠閑和自信的生活狀態(tài)。 ...
    夏玫小墨閱讀 902評論 0 3

友情鏈接更多精彩內容