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线程数翻倍性能翻倍_术业专攻 |