欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > java >内容正文

java

java反射克隆对象_Java反射 - 2(对象复制,父类域,内省)

发布时间:2025/3/20 java 48 豆豆
生活随笔 收集整理的这篇文章主要介绍了 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(对象复制,父类域,内省)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。