java如何用反射将一个对象复制给另一个对象

 更新时间:2023年09月25日 09:16:29   作者:YoungMirror  
这篇文章主要介绍了java如何用反射将一个对象复制给另一个对象问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

java用反射将一个对象复制给另一个对象

@SneakyThrows
    public static Object objectClone(Object newObject,Object oldObject){
        Field[] oldFields = oldObject.getClass().getDeclaredFields();
        Field newField;
        for (Field oldField : oldFields){
            oldField.setAccessible(true);
            newField = newObject.getClass().getDeclaredField(oldField.getName());
            newField.setAccessible(true);
            newField.set(newObject,oldField.get(oldObject));
        }
        return newObject;
    }

java复制一个对象使新对象和源对象值相同,地址不同

1. 实体(3个 模拟多层父级)支持多层父级和List,map的copy值

public class StudentDemo extends StudentF {
    private Integer stuId;
    private String stuName;
    private String stuPrice;
    private boolean flg;
    private List<String> listString;
    private HashMap<String, StuType> mapType;
    public HashMap<String, StuType> getMapType() {
        return mapType;
    }
    public void setMapType(HashMap<String, StuType> mapType) {
        this.mapType = mapType;
    }
    public List<String> getListString() {
        return listString;
    }
    public void setListString(List<String> listString) {
        this.listString = listString;
    }
    public boolean isFlg() {
        return flg;
    }
    public void setFlg(boolean flg) {
        this.flg = flg;
    }
    public StudentDemo(HashMap<String, StuType> mapType, List<StuType> listType, List<String> listString, Integer stuId, String stuName, String stuPrice, String stuSex, Integer stuAge, String stuNum, String stuTel, boolean isFlg) {
        this.stuId = stuId;
        this.stuName = stuName;
        this.stuPrice = stuPrice;
        super.setStudentSex(stuSex);
        super.setStudentAge(stuAge);
        super.setStuNum(stuNum);
        super.setTel(stuTel);
        this.flg = isFlg;
        this.listString = listString;
        super.setListType(listType);
        this.mapType = mapType;
    }
    public StudentDemo(){}
    @Override
    public String toString() {
        return "StudentDemo{" +
                "stuId=" + stuId +
                ", stuName='" + stuName + '\'' +
                ", stuPrice='" + stuPrice + '\'' +
                ", stuSex='" + super.getStudentSex() + '\'' +
                ", stuAge='" + super.getStudentAge() + '\'' +
                ", stuNum='" + super.getStuNum() + '\'' +
                ", stuTel='" + super.getTel() + '\'' +
                ", flg='" + flg + '\'' +
                ", listString='" + listString + '\'' +
                ", listType='" + super.getListType() + '\'' +
                ", mapType='" + mapType + '\'' +
                '}';
    }
    public Integer getStuId() {
        return stuId;
    }
    public void setStuId(Integer stuId) {
        this.stuId = stuId;
    }
    public String getStuName() {
        return stuName;
    }
    public void setStuName(String stuName) {
        this.stuName = stuName;
    }
    public String getStuPrice() {
        return stuPrice;
    }
    public void setStuPrice(String stuPrice) {
        this.stuPrice = stuPrice;
    }
}
public class StudentF extends StudentX {
    private String studentSex;
    private Integer studentAge;
    private List<StuType> listType;
    public List<StuType> getListType() {
        return listType;
    }
    public void setListType(List<StuType> listType) {
        this.listType = listType;
    }
    public String getStudentSex() {
        return studentSex;
    }
    public void setStudentSex(String studentSex) {
        this.studentSex = studentSex;
    }
    public Integer getStudentAge() {
        return studentAge;
    }
    public void setStudentAge(Integer studentAge) {
        this.studentAge = studentAge;
    }
}
public class StudentX {
    private String stuNum;
    private String Tel;
    public String getStuNum() {
        return stuNum;
    }
    public void setStuNum(String stuNum) {
        this.stuNum = stuNum;
    }
    public String getTel() {
        return Tel;
    }
    public void setTel(String tel) {
        Tel = tel;
    }
}

2. 工具类

package com.books.utils;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
 *  复制一个实体对象
 *  修改新对象时不影响源对象的值
 * @param <T> 项目中任意类型
 */
public class CopyObjectEntity<T> {
	/**
     *  复制实体方法
     * @param orderEntity 源对象
     * @param newEntity 新对象
     * @return 新对象
     */
    public T newPojo(Object orderEntity, Object newEntity){
        // 新对象
        T newPojo = null;
        try {
            // 源对象
            T orderPojo = (T)orderEntity;
            newPojo = (T)newEntity;
            // 获取所有方法,包括父类
            Method[] orderObject = orderPojo.getClass().getMethods();
            // 遍历所有方法
            for(int a = 0; a < orderObject.length; a ++){
                // 得到每一个方法名称
                String name = orderObject[a].getName();
                // 判断获取需要的(普通的字段都是get/set),这里获取get方法因为get到值才能赋值
                if(!name.equals("setClass") && !name.equals("class") && !name.equals("getClass") && name.startsWith("get")){
                    // 获取方法
                    Method method = orderPojo.getClass().getMethod(name, new Class[] {});
                    // 执行方法
                    Object value = method.invoke(orderPojo, new Object[] {});
                    // 拼接set方法
                    String aa = orderObject[a].getName().substring(3);
                    String bb = aa.substring(0, 1).toUpperCase();
                    String setter = bb + aa.substring(1);
                    // 创建描述器
                    PropertyDescriptor pd = new PropertyDescriptor(setter, newPojo.getClass());
                    //为上面声明的字段设置set方法(又称内省)
                    Method setMethod = pd.getWriteMethod();
                    // 执行set
                    setMethod.invoke(newPojo, value);
                }
                // 判断是boolean的字段get时为is
                if(!name.equals("setClass") && !name.equals("class") && !name.equals("getClass") && name.startsWith("is")){
                    Method method = orderPojo.getClass().getMethod(name, new Class[] {});
                    Object value = method.invoke(orderPojo, new Object[] {});
                    String aa = orderObject[a].getName().substring(2);
                    String bb = aa.substring(0, 1).toUpperCase();
                    String setter = bb + aa.substring(1);
                    PropertyDescriptor pd = new PropertyDescriptor(setter, newPojo.getClass());
                    //为上面声明的字段设置set方法(又称内省)
                    Method setMethod = pd.getWriteMethod();
                    // 执行set
                    setMethod.invoke(newPojo, value);
                }
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IntrospectionException e) {
            e.printStackTrace();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return newPojo;
    }
}

3. 测试

    public void test7(){
        List<String> ls = new ArrayList<>();
        ls.add("aa");
        ls.add("bb");
        ls.add("cc");
        List<StuType> listType = new ArrayList<>();
        listType.add(new StuType(1, "类型1"));
        listType.add(new StuType(2, "类型2"));
        HashMap<String, StuType> mapType = new HashMap<>();
        mapType.put("11", new StuType(11, "map1"));
        mapType.put("22", new StuType(22, "map2"));
        StudentDemo studentDemo = new StudentDemo(mapType, listType, ls,1, "aa" ,null, "男", 23, "010010", "15244669988", true);
        StudentDemo studentDemo1 = new StudentDemo();
        new CopyObjectEntity<StudentDemo>().newPojo(studentDemo, studentDemo1);
        System.out.println("复制完的新对象"+studentDemo1);
        studentDemo1.setStuId(22);
        studentDemo1.setStuName("你好啊");
        studentDemo1.setStuPrice("啦啦啦");
        studentDemo1.setStudentSex("女");
        studentDemo1.setStudentAge(20);
        studentDemo1.setStuNum("没有学号");
        studentDemo1.setTel("没有电话");
        studentDemo1.setFlg(false);
        List<String> ls1 = new ArrayList<>();
        ls1.add("33");
        ls1.add("44");
        ls1.add("55");
        List<StuType> listType1 = new ArrayList<>();
        listType1.add(new StuType(-1, "类型-1"));
        listType1.add(new StuType(-2, "类型-2"));
        HashMap<String, StuType> mapType1 = new HashMap<>();
        mapType1.put("11", new StuType(-11, "map-1"));
        mapType1.put("22", new StuType(-22, "map-2"));
        studentDemo1.setListType(listType1);
        studentDemo1.setMapType(mapType1);
        studentDemo1.setListString(ls1);
        System.out.println("源对象"+studentDemo);
        System.out.println("修改复制后对象"+studentDemo1);
        System.out.println("再次查看源对象"+studentDemo);
    }

4. 结果

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java中的connection reset 异常处理分析

    java中的connection reset 异常处理分析

    本文主要介绍了java中的connection reset 异常处理分析的相关资料,具有很好的参考价值。下面跟着小编一起来看下吧
    2017-04-04
  • Java超详细教你写一个斗地主洗牌发牌系统

    Java超详细教你写一个斗地主洗牌发牌系统

    这篇文章主要介绍了怎么用Java来你写一个斗地主种洗牌和发牌的功能,斗地主相信大家都知道,同时也知道每一局都要洗牌打乱顺序再发牌,本篇我们就来实现这个功能,感兴趣的朋友跟随文章往下看看吧
    2022-03-03
  • SpringBoot整合RocketMQ实现发送同步消息

    SpringBoot整合RocketMQ实现发送同步消息

    RocketMQ 是一款开源的分布式消息中间件,由阿里巴巴开源,它具有高可用性、高性能、低延迟等特点,广泛应用于阿里巴巴集团内部以及众多外部企业的业务系统中,本文给大家介绍了SpringBoot整合RocketMQ实现发送同步消息,需要的朋友可以参考下
    2024-04-04
  • SpringMVC框架的介绍与使用详解

    SpringMVC框架的介绍与使用详解

    SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,跟Spring,Mybatis框架并称为ssm,这篇文章主要介绍了SpringMVC框架的介绍与使用,需要的朋友可以参考下
    2022-08-08
  • Java详细讲解堆排序与时间复杂度的概念

    Java详细讲解堆排序与时间复杂度的概念

    本文主要介绍了java实现堆排序以及时间复杂度,堆排序这种排序算法是我们经常用到的,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • springcloud 服务降级的实现方法

    springcloud 服务降级的实现方法

    这篇文章主要介绍了springcloud 服务降级的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • java开发之闹钟的实现代码

    java开发之闹钟的实现代码

    本篇文章介绍了,在java中闹钟的实现代码。需要的朋友参考下
    2013-05-05
  • SpringBoot深入分析讲解监听器模式上

    SpringBoot深入分析讲解监听器模式上

    监听器模式,大家应该并不陌生,主要的组成要素包括了事件、监听器以及广播器;当事件发生时,广播器负责将事件传递给所有已知的监听器,而监听器会对自己感兴趣的事件进行处理
    2022-07-07
  • 10个避免Java内存泄露的最佳实践分享

    10个避免Java内存泄露的最佳实践分享

    即使有垃圾回收器的帮助,Java应用程序仍然可能遭遇内存泄漏问题,本文将介绍10个避免Java内存泄漏的最佳实践,大家可以根据需求自己进行选择
    2025-04-04
  • MyBatis中的XML实现和动态SQL实现示例详解

    MyBatis中的XML实现和动态SQL实现示例详解

    这篇文章主要介绍了MyBatis中的XML实现和动态SQL实现,我们可以将XML中重复出现的内容提取出来放到sql标签中,当需要用到sql标签中的内容时,用include标签将sql标签中的内容引进来即可,感兴趣的朋友跟随小编一起看看吧
    2024-02-02

最新评论