使用序列化的方式完全克隆对象

对象深度克隆一般有两种方式

1.实现 Cloneable 接口并重写 Object 类中的 clone()方法;

如果类中包含一个类,那么两个类都要实现clone()方法。

2.实现 Serializable 接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆,代码如下。

1.Test

package com.nightliar.bootdemo;

import java.io.*;

/**
 * Created by Nightliar
 * 2018-08-21 9:58
 */
public class Test {

    @org.junit.Test
    public void mains() throws Exception {
        User user1 = new User();
        user1.setId(12);
        user1.setName("zhangsan");
        Cat cat = new Cat();
        cat.setCatName("baoma");
        cat.setId(343L);
        user1.setCat(cat);
        System.out.println("原user1:" + user1);

        User user2 = Test.clone(user1);
        System.out.println("原user2:" + user2);

        user2.setName("lisi");
        user2.setId(2);
        Cat cat2 = new Cat();
        cat2.setCatName("benci");
        cat2.setId(999L);
        user2.setCat(cat2);
        System.out.println("新user2:" + user2);
        System.out.println("原user1:" + user1);

    }

    @SuppressWarnings("unchecked")
    public static <T extends Serializable> T clone(T obj) throws Exception {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bout);
        oos.writeObject(obj);
        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bin);
        return (T) ois.readObject();
        // 说明:调用 ByteArrayInputStream 或 ByteArrayOutputStream 对象的 close 方法没有任何意义
        // 这两个基于内存的流只要垃圾回收器清理对象就能够释放资源,这一点不同于对外部资源(如文件流)的释放
    }

}
结果:
原user1:User{id=12, cat=Cat{id=343, catName='baoma'}, name='zhangsan'}
原user2:User{id=12, cat=Cat{id=343, catName='baoma'}, name='zhangsan'}
新user2:User{id=2, cat=Cat{id=999, catName='benci'}, name='lisi'}
原user1:User{id=12, cat=Cat{id=343, catName='baoma'}, name='zhangsan'}

2.User

package com.nightliar.bootdemo;

import java.io.Serializable;

/**
 * Created by Nightliar
 * 2018-09-04 8:50
 */
public class User implements Serializable {
    private int id;
    private Cat cat;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" + "id=" + id + ", cat=" + cat + ", name='" + name + '\'' + '}';
    }
}

3.Cat

package com.nightliar.bootdemo;

import java.io.Serializable;

/**
 * Created by Nightliar
 * 2018-09-04 8:51
 */
public class Cat implements Serializable {
    private Long id;
    private String catName;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getCatName() {
        return catName;
    }

    public void setCatName(String catName) {
        this.catName = catName;
    }

    @Override
    public String toString() {
        return "Cat{" + "id=" + id + ", catName='" + catName + '\'' + '}';
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值