BeanUtils和PropertyUtils類是許多開源框架中頻繁使用的兩個工具,它們都能實現將一個類中的屬性拷貝到另一個類中,這個功能甚至是spring實現依賴注入的基礎。研究一下apache的comon包中如何實現這個兩個工具,可以發現它們都是使用java.lang.reflect和java.beans這兩個包下的幾個類來實現的。
/** 實現將源類屬性拷貝到目標類中
* @param source
* @param target
*/
public static void copyProperties(Object source, Object target) {
try {
//獲取目標類的屬性信息
BeanInfo targetbean = Introspector.getBeanInfo(target.getClass());
PropertyDescriptor[] propertyDescriptors = targetbean.getPropertyDescriptors();
//對每個目標類的屬性查找set方法,并進行處理
for (int i = 0; i < propertyDescriptors.length; i++) {
PropertyDescriptor pro = propertyDescriptors[i];
Method wm = pro.getWriteMethod();
if (wm != null) {//當目標類的屬性具有set方法時,查找源類中是否有相同屬性的get方法
BeanInfo sourceBean = Introspector.getBeanInfo(source.getClass());
PropertyDescriptor[] sourcepds = sourceBean.getPropertyDescriptors();
for (int j = 0; j < sourcepds.length; j++) {
if (sourcepds[j].getName().equals(pro.getName())) { //匹配
Method rm = sourcepds[j].getReadMethod();
//如果方法不可訪問(get方法是私有的或不可達),則拋出SecurityException
if (!Modifier.isPublic(rm.getDeclaringClass().getModifiers())) {
rm.setAccessible(true);
}
//獲取對應屬性get所得到的值
Object value = rm.invoke(source,new Object[0]);
if (!Modifier.isPublic(wm.getDeclaringClass().getModifiers())) {
wm.setAccessible(true);
}
//調用目標類對應屬性的set方法對該屬性進行填充
wm.invoke((Object) target, new Object[] { value });
break;
}
}
}
}
} catch (IntrospectionException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
這里我們通過編寫一個將一個類的所有屬性拷貝到另一個類的相應屬性的方法來分析是如何實現拷貝功能的.先把方法放上來:














































兩個工具的其他方法實現雖然有點差別,但原理都跟上面的例子差不多,有興趣的話可以寫個測試類試試是否可以使用.
轉自: http://lemonfamily.blogdriver.com/lemonfamily/1240784.html