Java內省詳解

內省的解釋

內省在wiki上的解釋:

在計算機科學中,內省是指計算機程序在運行時(Run time)檢查對象(Object)類型的一種能力,通常也可以稱作運行時類型檢查。
不應該將內省和反射混淆。相對於內省,反射更進一步,是指計算機程序在運行時(Run time)可以訪問、檢測和修改它本身狀態或行爲的一種能力。


內省和反射有什麼區別

反射式在運行狀態把Java類中的各種成分映射成相應的Java類,可以動態的獲取所有的屬性以及動態調用任意一個方法,強調的是運行狀態。
內省機制是通過反射來實現的,BeanInfo用來暴露一個bean的屬性、方法和事件,以後我們就可以操縱該JavaBean的屬性


這裏寫圖片描述
在Java內省中,用到的基本上就是上述幾個類。
通過BeanInfo這個類就可以獲取到類中的方法和屬性,具體的可以參考JDK文檔


內省的代碼實現

1.通過PropertyDescriptor修改屬性方式

[java] view plain copy print?
package com.query;  

import java.beans.PropertyDescriptor;  
import java.lang.reflect.Method;  

public class BeanInfoUtil {  
    public static void setProperty(UserInfo userInfo,String userName)throws Exception{  
        PropertyDescriptor propDesc=new PropertyDescriptor(userName,UserInfo.class);  
        Method methodSetUserName=propDesc.getWriteMethod();  
        methodSetUserName.invoke(userInfo, "wong");  
        System.out.println("set userName:"+userInfo.getUserName());  
    }  

    public static void getProperty(UserInfo userInfo,String userName)throws Exception{  
        PropertyDescriptor proDescriptor =new PropertyDescriptor(userName,UserInfo.class);  
        Method methodGetUserName=proDescriptor.getReadMethod();  
        Object objUserName=methodGetUserName.invoke(userInfo);  
        System.out.println("get userName:"+objUserName.toString());  
    }  

}  

2.通過Introspector類修改屬性

package com.query;  

import java.beans.BeanInfo;  
import java.beans.Introspector;  
import java.beans.PropertyDescriptor;  
import java.lang.reflect.Method;  

public class BeanInfoUtil2 {  
    public static void setPropertyByIntrospector(UserInfo userInfo,  
            String userName) throws Exception {  

        BeanInfo beanInfo = Introspector.getBeanInfo(UserInfo.class);  
        PropertyDescriptor[] proDescrtptors = beanInfo.getPropertyDescriptors();  
        if (proDescrtptors != null && proDescrtptors.length > 0) {  
            for (PropertyDescriptor propDesc : proDescrtptors) {  
                if (propDesc.getName().equals(userName)) {  
                    Method methodSetUserName = propDesc.getWriteMethod();  
                    methodSetUserName.invoke(userInfo, "alan");  
                    System.out  
                            .println("set userName:" + userInfo.getUserName());  
                    break;  
                }  
            }  
        }  
    }  

    public static void getPropertyByIntrospector(UserInfo userInfo,  
            String userName) throws Exception {  
        BeanInfo beanInfo = Introspector.getBeanInfo(UserInfo.class);  
        PropertyDescriptor[] proDescrtptors = beanInfo.getPropertyDescriptors();  
        if (proDescrtptors != null && proDescrtptors.length > 0) {  
            for (PropertyDescriptor propDesc : proDescrtptors) {  
                if (propDesc.getName().equals(userName)) {  
                    Method methodGetUserName = propDesc.getReadMethod();  
                    Object objUserName = methodGetUserName.invoke(userInfo);  
                    System.out  
                            .println("get userName:" + objUserName.toString());  
                    break;  
                }  
            }  
        }  
    }  

}  

注意事項,在上述修改JavaBean屬性的時候,如果數據類型不對的話,會報錯。例如BeanInfoUtil.setProperty(userInfo, “age”);報錯是應爲age屬性是int數據類型,而setProperty方法裏面默認給age屬性賦的值是String類型。所以會爆出argument type mismatch參數類型不匹配的錯誤信息。
爲了解決上述問題,Apache開發了一套簡單、易用的API來操作Bean的屬性——BeanUtils工具包。
  BeanUtils工具包:下載:http://commons.apache.org/beanutils/ 注意:應用的時候還需要一個logging包http://commons.apache.org/logging/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章