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;
        import java.beans.IntrospectionException;
        import java.beans.Introspector;
        import java.beans.PropertyDescriptor;
    除了反射用到的類需要引入外,內省需要引入的類如上所示,它們都屬於java.beans包中的類,自己寫程序的時候也不能忘了引入相應的包或者類。下面代碼片斷是一個設置某個JavaBean類某個屬性的關鍵代碼:
        private static void setObjectProperty(ReflectPoint pt1, int value,String propName) throws IntrospectionException, IllegalAccessException, InvocationTargetException {
            /*BeanInfo bean = 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 = new PropertyDescriptor("x",ReflectPoint.class);
            Method mSetX = property.getWriteMethod();
            mSetX.invoke(pt1, value);
        }
    代碼中注釋的語句代表一種方式,最后的三行代表另外一種設置相應類相應屬性的方式。從簡潔上來說,第二種方式顯然更優雅。第一種方式中首先是獲得相應javaBean的類信息bean,用的BeanInfo這個類來描述的。然后就能夠通過getPropertyDescriptors方法獲取屬性描述數組對象。最后從數組中取去一個個的屬性對象進行操作——獲取相應的讀寫方法,然后調用相應的讀寫方法。這些是通過反射機制做到的。由於這種方式比較麻煩,如果只調用其中一種方法,就要遍歷一次屬性描述數組,所以就產生了第二種方式,直接通過傳入屬性名稱,相應的javaBean類型參數,構造出一個需要的PropertyDescriptor對象,然后再進行調用。
    理解了相應的原理,那些現成的工具用起來就會更舒服,如Beanutils與PropertyUtils工具。這兩個工具設置屬性的時候一個主要區別是PropertyUtils.getPropety方法獲得的屬性值的類型為該屬性本來的類型,而BeanUtils.getProperty則是將該屬性的值轉換成字符串后才返回。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM