复杂对象的深度克隆

说到对象的复制或者克隆,大家可能会想到一下几种工具类:

1、BO克隆:BeanUtils.copyProperties(srcObj,destObj)   spring框架提供的工具类,第一个参数源数据,第二个 参数目标对象。注意源对象和目标对象中的属性名和属性类型必须完全一致,才能进行复制;该方法主要用于复制bo等

2、List克隆:Collections.copy(destList,srcList)    来自于java.util.Collections。第一个参数是目标对象,第二个参数是源对象,正好                        beanUtils.copyProperties()相反,该方法可以用于复制list,在使用时,destList必须进行初始化容量

            例如:List<String> dic = new ArrayList<String>(Arrays.asList(new String[src.size()]))

            错误的初始化:List<String> dst = new ArrayList<String>(src.size());因为这是设定集合是容量是多大,而不是初始化集合。

 

本示例中采用ParentClass 、SubClass的结构在下面的例子的贴出来了。

public static void main(String [] args){
    ParentClass parentClass = new ParentClass();
    SubClass sub1 = new SubClass();
    sub1.setSubAge(11);
    sub1.setSubName("sub11");
    SubClass sub2 = new SubClass();
    sub2.setSubName("sub22");
    sub2.setSubAge(22);
    SubClass sub3 = new SubClass();
    sub3.setSubName("sub33");
    sub3.setSubAge(33);
    List<SubClass> list = new ArrayList();
    list.add(sub1);
    list.add(sub2);
    parentClass.setList(list);
    parentClass.setSubClass(sub3);
    parentClass.setFatherName("fatherName");
    parentClass.setFatherAge(88);
    List<ParentClass> srcList = new ArrayList<>();
    srcList.add(parentClass);
    List<ParentClass> destList = new ArrayList(Arrays.asList(new String[srcList.size()]));
    Collections.copy(destList, srcList);
    
    
}

但是还有一种方法采用深度克隆,实现代码如下

/**
 *  该方法适用于复杂对象的深度克隆
 * @param srcObj   源对象
 * @return Object   目标对象
 * @throws Exception
 */
static Object deepClone(Serializable srcObj) throws Exception {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    ObjectOutputStream oo = new ObjectOutputStream(out);
    oo.writeObject(srcObj);
    ByteArrayInputStream in = new ByteArrayInputStream(out
            .toByteArray());
    ObjectInputStream oi = new ObjectInputStream(in);
    return oi.readObject();
}

该方法使用需注意:参数 srcObj 必须实现了序列化接口Serializable,这个方法最大的好处是,不管srcObj内部属性多么复杂,嵌套层级多大,都可以进行深度克隆。

测试示例如下:

BO1:

public class SubClass implements Serializable {
    private static final long serialVersionUID = 3232707926247447408L;
 
    private String subName;
    private int subAge;
    .....setter/getter方法省略....
}
BO2:
public class ParentClass implements Serializable {
    private static final long serialVersionUID = -3556157995320461937L;
    private String fatherName;
    private int fatherAge;
    
    private List<SubClass> list;
    
    private SubClass subClass;
   .....setter/getter方法省略....
}

测试:

public class MyTest {

    /**
     *
     * @param srcObj   源对象
     * @return Object   目标对象
     * @throws Exception
     */
    static Object deepClone(Serializable srcObj) throws Exception {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ObjectOutputStream oo = new ObjectOutputStream(out);
        oo.writeObject(srcObj);
        ByteArrayInputStream in = new ByteArrayInputStream(out
                .toByteArray());
        ObjectInputStream oi = new ObjectInputStream(in);
        return oi.readObject();
    }



    public static void main(String [] args){
        ParentClass parentClass = new ParentClass();
        SubClass sub1 = new SubClass();
        sub1.setSubAge(11);
        sub1.setSubName("aaa11");
        SubClass sub2 = new SubClass();
        sub2.setSubName("bbb22");
        sub2.setSubAge(22);
        SubClass sub3 = new SubClass();
        sub3.setSubName("ccc33");
        sub3.setSubAge(33);
        List<SubClass> list = new ArrayList();
        list.add(sub1);
        list.add(sub2);
        parentClass.setList(list);
        parentClass.setSubClass(sub3);

        try {
            Object obj = deepClone(parentClass);
        } catch (Exception e) {
            System.err.println("EXECPTION=" + e.getMessage());
        }


    }

}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一路奔跑1314

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值