1. 程式人生 > >Java讀書筆記十一(Java中的內省機制)

Java讀書筆記十一(Java中的內省機制)

1.前言

最近在學習Java的時候,突然發現了這個概念,鑑於好奇心的壓迫,於是打算寫一篇部落格來總結一下。

 2.什麼是內省機制

為了讓程式設計師們更好的從左Java物件的屬性,SUN公司開發了一套API,就被我們稱為“內省”,有利於我們對類物件的屬性的操作,減少了程式碼的數量。

 3.內省和反射有什麼區別

反射式在執行狀態把Java類中的各種成分對映成相應的Java類,可以動態的獲取所有的屬性以及動態呼叫任意一個方法,強調的是執行狀態。

內省機制是通過反射來實現的,BeanInfo用來暴露一個bean的屬性、方法和事件,以後我們就可以操縱該JavaBean的屬性

 4.一張圖總結


在Java內省中,用到的基本上就是上述幾個類。

通過BeanInfo這個類就可以獲取到類中的方法和屬性,具體的可以參考JDK文件

 5.Demo展示

5.1.通過PropertyDescriptor修改屬性方式

  1. package com.query;  
  2. import java.beans.PropertyDescriptor;  
  3. import java.lang.reflect.Method;  
  4. publicclass BeanInfoUtil {  
  5.     publicstaticvoid setProperty(UserInfo userInfo,String userName)throws Exception{  
  6.         PropertyDescriptor propDesc=new
     PropertyDescriptor(userName,UserInfo.class);  
  7.         Method methodSetUserName=propDesc.getWriteMethod();  
  8.         methodSetUserName.invoke(userInfo, "wong");  
  9.         System.out.println("set userName:"+userInfo.getUserName());  
  10.     }  
  11.     publicstaticvoid getProperty(UserInfo userInfo,String userName)
    throws Exception{  
  12.         PropertyDescriptor proDescriptor =new PropertyDescriptor(userName,UserInfo.class);  
  13.         Method methodGetUserName=proDescriptor.getReadMethod();  
  14.         Object objUserName=methodGetUserName.invoke(userInfo);  
  15.         System.out.println("get userName:"+objUserName.toString());  
  16.     }  
  17. }  

5.2.通過Introspector類修改屬性
  1. package com.query;  
  2. import java.beans.BeanInfo;  
  3. import java.beans.Introspector;  
  4. import java.beans.PropertyDescriptor;  
  5. import java.lang.reflect.Method;  
  6. publicclass BeanInfoUtil2 {  
  7.     publicstaticvoid setPropertyByIntrospector(UserInfo userInfo,  
  8.             String userName) throws Exception {  
  9.         BeanInfo beanInfo = Introspector.getBeanInfo(UserInfo.class);  
  10.         PropertyDescriptor[] proDescrtptors = beanInfo.getPropertyDescriptors();  
  11.         if (proDescrtptors != null && proDescrtptors.length > 0) {  
  12.             for (PropertyDescriptor propDesc : proDescrtptors) {  
  13.                 if (propDesc.getName().equals(userName)) {  
  14.                     Method methodSetUserName = propDesc.getWriteMethod();  
  15.                     methodSetUserName.invoke(userInfo, "alan");  
  16.                     System.out  
  17.                             .println("set userName:" + userInfo.getUserName());  
  18.                     break;  
  19.                 }  
  20.             }  
  21.         }  
  22.     }  
  23.     publicstaticvoid getPropertyByIntrospector(UserInfo userInfo,  
  24.             String userName) throws Exception {  
  25.         BeanInfo beanInfo = Introspector.getBeanInfo(UserInfo.class);  
  26.         PropertyDescriptor[] proDescrtptors = beanInfo.getPropertyDescriptors();  
  27.         if (proDescrtptors != null && proDescrtptors.length > 0) {  
  28.             for (PropertyDescriptor propDesc : proDescrtptors) {  
  29.                 if (propDesc.getName().equals(userName)) {  
  30.                     Method methodGetUserName = propDesc.getReadMethod();  
  31.                     Object objUserName = methodGetUserName.invoke(userInfo);  
  32.                     System.out  
  33.                             .println("get userName:" + objUserName.toString());  
  34.                     break;  
  35.                 }  
  36.             }  
  37.         }  
  38.     }  
  39. }  


注意事項,在上述修改JavaBean屬性的時候,如果資料型別不對的話,會報錯。例如BeanInfoUtil.setProperty(userInfo, "age");報錯是應為age屬性是int資料型別,而setProperty方法裡面預設給age屬性賦的值是String型別。所以會爆出argument type mismatch引數型別不匹配的錯誤資訊。