java 內省機制

內省(IntroSpector)是Java 語言對 Bean 類屬性、事件的一種缺省處理方法。例如類 A 中有屬性 name, 那我們可以通過 getName,setName 來得到其值或者設置新的值。通過 getName/setName 來訪問 name 屬性,這就是默認的規則。 Java 中提供了一套 API 用來訪問某個屬性的 getter/setter 方法,通過這些 API 可以使你不需要了解這個規則(但你最好還是要搞清楚),這些 API 存放於包 java.beans 中,一般的做法是通過類 Introspector 的 getBeanInfo方法 來獲取某個對象的 BeanInfo 信息,然後通過 BeanInfo 來獲取屬性的描述器(PropertyDescriptor),通過這個屬性描述器就可以獲取某個屬性對應的 getter/setter 方法,然後我們就可以通過反射機制來調用這些方法。

我們又通常把javabean的實例對象稱之爲值對象(Value Object),因爲這些bean中通常只有一些信息字段和存儲方法,沒有功能性方法。

 一個JavaBean類可以不當JavaBean用,而當成普通類用。JavaBean實際就是一種規範,當一個類滿足這個規範,這個類就能被其它特定的類調用。一個類被當作javaBean使用時,JavaBean的屬性是根據方法名推斷出來的,它根本看不到java類內部的成員變量。去掉set前綴,然後取剩餘部分,如果剩餘部分的第二個字母是小寫的,則把剩餘部分的首字母改成小的。下面就用前面的講解的反射方式來設置或讀取JavaBean的屬性:
        import java.beans.BeanInfo;
        importjava.beans.IntrospectionException;
        import java.beans.Introspector;
        importjava.beans.PropertyDescriptor;
    除了反射用到的類需要引入外,內省需要引入的類如上所示,它們都屬於java.beans包中的類,自己寫程序的時候也不能忘了引入相應的包或者類。下面代碼片斷是一個設置某個JavaBean類某個屬性的關鍵代碼:
        private static voidsetObjectProperty(ReflectPoint pt1, int value,String propName) throwsIntrospectionException, IllegalAccessException, InvocationTargetException{
            /*BeanInfobean = Introspector.getBeanInfo(ReflectPoint.class);
           PropertyDescriptor [] properties = bean.getPropertyDescriptors();
           for(PropertyDescriptor property: properties)
            {
               if(property.getName().equals(propName))
               {
                   Method mSetX = property.getWriteMethod();
                   mSetX.invoke(pt1, value);
                   break;
               }
            }*/
           PropertyDescriptor property = newPropertyDescriptor("x",ReflectPoint.class);
            Method mSetX= property.getWriteMethod();
           mSetX.invoke(pt1, value);
        }
    代碼中註釋的語句代表一種方式,最後的三行代表另外一種設置相應類相應屬性的方式。從簡潔上來說,第二種方式顯然更優雅。第一種方式中首先是獲得相應javaBean的類信息bean,用的BeanInfo這個類來描述的。然後就能夠通過getPropertyDescriptors方法獲取屬性描述數組對象。最後從數組中取去一個個的屬性對象進行操作——獲取相應的讀寫方法,然後調用相應的讀寫方法。這些是通過反射機制做到的。由於這種方式比較麻煩,如果只調用其中一種方法,就要遍歷一次屬性描述數組,所以就產生了第二種方式,直接通過傳入屬性名稱,相應的javaBean類型參數,構造出一個需要的PropertyDescriptor對象,然後再進行調用。
    理解了相應的原理,那些現成的工具用起來就會更舒服,如Beanutils與PropertyUtils工具。這兩個工具設置屬性的時候一個主要區別是PropertyUtils.getPropety方法獲得的屬性值的類型爲該屬性本來的類型,而BeanUtils.getProperty則是將該屬性的值轉換成字符串後才返回。

 

發佈了28 篇原創文章 · 獲贊 9 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章