Java对象的深浅拷贝

对象的拷贝

浅拷贝

对象和对象的拷贝指向的是同一块内存区域,修改一个会影响到另一个;

public class Person implements Cloneable{
    // 对象的引用
    Car car;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return "Person{" +
                "car=" + car +
                '}';
    }
}

public class Car implements Cloneable{
    Integer id;
    String name;

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

public class OrdinaryCopy {
    public static void main(String[] args){
        Person p = new Person();
        p.car = new Car();
        p.car.name = "123";

        // 浅拷贝,指向的是同一块内存区域
        Person p1 = (Person) p.clone();
        p1.car.id = 1;

        System.out.println(p);
        System.out.println(p1);
    }
}

// 结果
Person{car=Car{id=1, name='123'}}
Person{car=Car{id=1, name='123'}}

深拷贝

对象和对象的拷贝指向内存区域不同,修改一个不会影响到另一个;

实现Cloneable接口

public class Car implements Cloneable{
    Integer id;
    String name;

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

    @Override
    protected Object clone() throws CloneNotSupportedException {
        // 因为官方提供的类型的克隆基本都无需我们自己去做
        // Car类没有别的引用类型,所以我们无需针对特定类型重写clone
        return super.clone();
    }
}

public class Person implements Cloneable{
    Car car;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person n = (Person) super.clone();
        // 由于有引用类型,所以需要调用引用类型的clone方法
        if (car != null) {
            n.car = (Car) car.clone();
        }
        return n;
    }

    @Override
    public String toString() {
        return "Person{" +
                "car=" + car +
                '}';
    }
}

public class T {
    public static void main(String[] args){
        Person p = new Person();
        p.car = new Car();
        p.car.name = "123";

        Person p1 = (Person) p.clone();
        p1.car.id = 1;

        System.out.println(p);
        System.out.println(p1);

    }
}

// 结果
Person{car=Car{id=null, name='123'}}
Person{car=Car{id=1, name='123'}}

实现Serializable接口

public class Car implements Serializable {
    Integer id;
    String name;

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

public class Person implements Serializable {
    Car car;

    @Override
    public String toString() {
        return "Person{" +
                "car=" + car +
                '}';
    }

    public Person deepClone() throws IOException, ClassNotFoundException {
        // 用字节流输出
        ByteOutputStream byteOut = new ByteOutputStream();
        ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
        // 把对象刷新到字节流中
        objOut.writeObject(this);
        objOut.flush();
        // 获取序列化之后的字节流数据
        byte[] data = byteOut.getBytes();
        
        // 将数据导入到字节获取流
        ByteInputStream byteIn = new ByteInputStream(data, data.length);
        ObjectInputStream objIn = new ObjectInputStream(byteIn);

        // 读出数据
        Person res = (Person) objIn.readObject();
        try {
            byteOut.close();
            objOut.close();
            byteIn.close();
            objIn.close();
        } finally {
            byteOut.close();
            objOut.close();
            byteIn.close();
            objIn.close();
        }

        return res;
    }
}

public class SeriTest {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Person p = new Person();
        p.car = new Car();
        p.car.name = "123";

        Person p1 = p.deepClone();
        p1.car.id = 1;

        System.out.println(p);
        System.out.println(p1);
    }
}

// 结果
Person{car=Car{id=null, name='123'}}
Person{car=Car{id=1, name='null'}}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值