1.補充。BeanUtils的效率問題:
BeanUtils.copyProperties(dest,orgi);實際上是調用的 PropertyUtils.copyProterties(dest,orgi)這個方法來實現的;這個方法的效率是非常低的。通過查看原代碼:發現屬性之間的COPY。主要用到了。java.beans包里面的相關類和方法。對於原對象(orgi).首先獲得BeanInfo類型的對象。如Introspector.getBeanInfo(a.class)。 這個BeanInfo類型的實例。包含了所有的Class類對象的信息。如果有父類。將首先加載獲得父類的信息。通過BeanInfo對象。可以獲得PropertyDescriptor[] 的數組。通過這個數組。可以獲得原對象(orgi)的所有屬性以及屬性的值。
在BeanUtils.copyProperties();方法中。首先循環獲得原對象的一個屬性。和屬性對應的值。然后根據這個屬性。循環目的對象(dest)的屬性。找出兩個屬性一致的那個屬性。然后通過,PropertyDescriptor對象中,獲得WriteMethod的一個Method 類型對象。最好通過反射。寫入屬性的值到目標對象對應的屬性。假如:原來對象有10個屬性。目標對象有10個屬性。則在整個copy方法中。需要執行至少10×10比較。少於10×10次的賦值。效率將非常低下。
2.補充。關於BeanInfo類型對象。
BeanInfo對象。有較多的方法。主要的有兩個。getPropertyDescriptor().返回一個PropertyDescriptor類型的數組。該類型對象包括父類Object.對象的class屬性。
另外一個是。getMethodDescriptor().返回的是一個MethodDescriptor類型的數組。這個數組中,包括對應Bean中的所有方法的屬性。甚至是Object。類型定義的。wait().notify()等方法。 關於BeanInfo用法的簡單測試:
BeanInfo bif = Introspector.getBeanInfo(TFeeItemR.class); PropertyDescriptor[] pd = bif.getPropertyDescriptors(); for(int i=0;i<pd.length;i++){ System.out.println("name:"+pd[i].getName()); System.out.println("read method name:"+pd[i]. getReadMethod ().getName()); System.out.println("displayname:"+pd[i].getDisplayName()); } MethodDescriptor[] md = bif.getMethodDescriptors();for(int m=0;m<md.length;m++){ System.out.println("name:"+md[m].getName()); System.out.println("method name:"+md[m].getMethod().getName()); System.out.println("displayname:"+md[m].getDisplayName()); } BeanDescriptor bd = bif.getBeanDescriptor(); System.out.println("display name:" + bd.getDisplayName()); System.out.println("name:" + bd.getName()); EventSetDescriptor[] esd = bif.getEventSetDescriptors(); for(int m=0;m<esd.length;m++){ System.out.println("name:"+esd[m].getName()); System.out.println("method name:"+esd[m].getGetListenerMethod().getName()); System.out.println("method name:"+esd[m].getRemoveListenerMethod().getName()); System.out.println("method name:"+esd[m].getAddListenerMethod().getName()); System.out.println("displayname:"+esd[m].getDisplayName()); }
