java反射克隆对象_Java反射 - 2(对象复制,父类域,内省)
為什么要復制對象?假設有個類Car,包含name,color2個屬性,那么將car1對象復制給car2對象,只需要car2.setName(car1.getName)與car2.setColor(car1.getColor)兩部操作即可。
實際項目中有很多類都有超過幾十個,甚至上百個字段,這時如果采用以上方式,將會有很大的代碼工作量與重復勞動。解決方法是使用反射機制。
首先有2個類如下
1 /**
2 * Created by yesiming on 16-11-19.3 */
4 public classCar {5 privateString name;6 privateString color;7 //省略set/get
8 }9 }
1 /**
2 * Created by yesiming on 16-11-20.3 */
4 public class Kia extendsCar{5 privateString model;6 //省略set/get
7 }
我們先操作入職Kia的域
1 /**
2 * 通過反射進行對象復制(漏洞:不能復制父類中的域)3 *@throwsException4 */
5 @Test6 public void copyObject() throwsException{7 User src = new User(); //源對象
8 src.setId(1);9 src.setName("yesiming");10 User target = new User(); //目標對象
11 Class clazz = User.class;12 Field[] fields = clazz.getDeclaredFields(); //得到該類聲明的域(不包含父類的域)
13 for(Field field : fields) {14 if(!field.isAccessible())15 field.setAccessible(true); //設置可訪問
16 field.set(target, field.get(src)); //從源對象get值set到目標對象
17 }18 //輸出顯示
19 for(Field field : fields) {20 System.out.println(field.get(target));21 }22 }
由于getDeclaredFields方法不能得到超類中的域,所以上述操作有缺陷,甚至不具有實際意義
下面是如何得到超類中的域,使用遞歸即可
1 /**
2 * 輸出所有域,包括父類中的域(通過遞歸實現)3 */
4 public voidshowAllField(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) { //結束遞歸
14 showAllField(superClazz); //遞歸
15 }16 }17
18 @Test19 public voidshowAllFieldTest() {20 Class clazz = Kia.class;21 showAllField(clazz);22 }
運行結果如下:
------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
那么好,結合上述2種操作,就能寫出具有實用價值的類復制方法了嗎?
當然不是,Java中操作Bean的專業戶是內省,Introspector
1 /**
2 * 通過專業操作JavaBean的內省,Introspector復制有繼承的類3 *@throwsException4 */
5 @Test6 public void showProfile() throwsException {7
8 Kia k1 = new Kia(); //源對象,繼承自Car
9 k1.setName("起亞"); //這是Car中的域
10 k1.setColor("白色"); //這是Car中的域
11 k1.setModel("K4");12 Kia k2 = new Kia(); //目標對象
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不配對就不復制
21 continue;22 }23 //反射set目標對象中的域
24 pd.getWriteMethod().invoke(k2, pd.getReadMethod().invoke(k1));25 }26 System.out.println(k2.getName() + k2.getModel() +k2.getColor());27 }
總結
以上是生活随笔為你收集整理的java反射克隆对象_Java反射 - 2(对象复制,父类域,内省)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我的世界boat运行库JAVA10_我的
- 下一篇: java线程数翻倍性能翻倍_术业专攻 |