Java反射 - 2(对象复制,父类域,内省)
生活随笔
收集整理的這篇文章主要介紹了
Java反射 - 2(对象复制,父类域,内省)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
為什么要復(fù)制對象?假設(shè)有個類Car,包含name,color2個屬性,那么將car1對象復(fù)制給car2對象,只需要car2.setName(car1.getName)與car2.setColor(car1.getColor)兩部操作即可。
實際項目中有很多類都有超過幾十個,甚至上百個字段,這時如果采用以上方式,將會有很大的代碼工作量與重復(fù)勞動。解決方法是使用反射機制。
首先有2個類如下
1 /** 2 * Created by yesiming on 16-11-19. 3 */ 4 public class Car { 5 private String name; 6 private String color; 7 // 省略set/get 8 } 9 } 1 /** 2 * Created by yesiming on 16-11-20. 3 */ 4 public class Kia extends Car{ 5 private String model; 6 // 省略set/get 7 }我們先操作入職Kia的域
1 /** 2 * 通過反射進(jìn)行對象復(fù)制(漏洞:不能復(fù)制父類中的域) 3 * @throws Exception 4 */ 5 @Test 6 public void copyObject() throws Exception{ 7 User src = new User(); // 源對象 8 src.setId(1); 9 src.setName("yesiming"); 10 User target = new User(); // 目標(biāo)對象 11 Class clazz = User.class; 12 Field[] fields = clazz.getDeclaredFields(); // 得到該類聲明的域(不包含父類的域) 13 for(Field field : fields) { 14 if(!field.isAccessible()) 15 field.setAccessible(true); // 設(shè)置可訪問 16 field.set(target, field.get(src)); // 從源對象get值set到目標(biāo)對象 17 } 18 // 輸出顯示 19 for(Field field : fields) { 20 System.out.println(field.get(target)); 21 } 22 }由于getDeclaredFields方法不能得到超類中的域,所以上述操作有缺陷,甚至不具有實際意義
下面是如何得到超類中的域,使用遞歸即可
1 /** 2 * 輸出所有域,包括父類中的域(通過遞歸實現(xiàn)) 3 */ 4 public void showAllField(Class clazz) { 5 Field[] fields = clazz.getDeclaredFields(); 6 System.out.println("------" + clazz.toString() + "------"); 7 if(fields != null && fields.length > 0) { 8 for(Field field : fields) { 9 System.out.println(field); 10 } 11 } 12 Class superClazz = clazz.getSuperclass(); 13 if(superClazz != Object.class) { // 結(jié)束遞歸 14 showAllField(superClazz); // 遞歸 15 } 16 } 17 18 @Test 19 public void showAllFieldTest() { 20 Class clazz = Kia.class; 21 showAllField(clazz); 22 }運行結(jié)果如下:
------class o1.o1_a.Kia------ private java.lang.String o1.o1_a.Kia.model ------class o1.o1_a.Car------ private java.lang.String o1.o1_a.Car.name private java.lang.String o1.o1_a.Car.color?那么好,結(jié)合上述2種操作,就能寫出具有實用價值的類復(fù)制方法了嗎?
當(dāng)然不是,Java中操作Bean的專業(yè)戶是內(nèi)省,Introspector
1 /** 2 * 通過專業(yè)操作JavaBean的內(nèi)省,Introspector復(fù)制有繼承的類 3 * @throws Exception 4 */ 5 @Test 6 public void showProfile() throws Exception { 7 8 Kia k1 = new Kia(); // 源對象,繼承自Car 9 k1.setName("起亞"); // 這是Car中的域 10 k1.setColor("白色"); // 這是Car中的域 11 k1.setModel("K4"); 12 Kia k2 = new Kia(); // 目標(biāo)對象 13 14 BeanInfo beanInfo = Introspector.getBeanInfo(Kia.class); // 得到Kia的Bean信息 15 PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); //通過BeanInfo得到域的描述符 16 for (PropertyDescriptor pd : pds) { 17 if (pd.getName() == "getClass()") { 18 continue; 19 } 20 if (pd.getReadMethod() == null || pd.getWriteMethod() == null) { // 如果set, get不配對就不復(fù)制 21 continue; 22 } 23 // 反射set目標(biāo)對象中的域 24 pd.getWriteMethod().invoke(k2, pd.getReadMethod().invoke(k1)); 25 } 26 System.out.println(k2.getName() + k2.getModel() + k2.getColor()); 27 }?
轉(zhuǎn)載于:https://www.cnblogs.com/simiie/p/6081977.html
總結(jié)
以上是生活随笔為你收集整理的Java反射 - 2(对象复制,父类域,内省)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cassandra 3.x官方文档(1)
- 下一篇: nodejs 获取文件夹中所有文件、图片