Java深拷贝和浅拷贝详解(看这篇就够了)

Java深拷贝和浅拷贝详解(看这篇就够了)-mikechen

Java深拷贝和浅拷贝是在编程中经常用到的,下面我就来详解Java深拷贝和浅拷贝@mikechen

Java浅拷贝

1.Java浅拷贝简介

浅拷贝,英文名是Shallow Copy,是一种对象复制的方式,浅拷贝仅复制了对象的表层结构,而不涉及嵌套对象的复制。

 

2.Java浅拷贝思想

浅拷贝的思想是创建一个新对象,将原始对象的字段值复制到新对象中,但对于原始对象内部的引用类型字段,只复制引用而不创建新的嵌套对象。

浅拷贝的主要思想可以总结为以下几点:

  • 复制对象本身: 浅拷贝首先会创建一个新对象,以及与原始对象相同的字段。
  • 复制引用: 对于原始对象内部的引用类型字段,浅拷贝会将引用复制到新对象中,而不会创建新的嵌套对象。
  • 共享引用对象: 这意味着原始对象和浅拷贝对象会共享相同的引用对象,对引用对象的修改会在两个对象之间共享。

 

3.Java浅拷贝优缺点

浅拷贝的优点在于它的速度相对较快,因为它不需要递归地复制所有嵌套对象。

然而它也有致命的的缺点,主要包含如下3点:

1)共享引用对象带来的问题

浅拷贝会共享原始对象和拷贝对象之间的引用对象,这意味着,如果你修改了拷贝对象内部的引用对象,原始对象也会受到影响,反之亦然。

这可能导致意外的副作用,特别是在多线程环境下,可能会出现并发问题。

2)不适用于嵌套对象

如果原始对象内部有多层嵌套的引用对象,浅拷贝只会复制最外层的引用,而不会递归复制内部的嵌套对象。

这可能导致拷贝对象仍然共享内部嵌套对象,无法实现真正的独立性。

3)无法实现深层克隆

浅拷贝无法实现对对象及其内部所有引用对象的完全独立复制,因此在需要完全独立的深层克隆时,浅拷贝不适用。

 

4.Java浅拷贝实现

在Java中,使用clone()方法可以实现浅拷贝,如下所示:

class Person implements Cloneable {
    String name;
    Age age;

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

class Age {
    int years;
}

public class ShallowCopyExample {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person();
        person1.name = "Alice";
        person1.age = new Age();
        person1.age.years = 30;

        Person person2 = (Person) person1.clone();

        System.out.println(person1.age.years); // Output: 30
        System.out.println(person2.age.years); // Output: 30

        person2.age.years = 40;

        System.out.println(person1.age.years); // Output: 40 (original object is affected)
        System.out.println(person2.age.years); // Output: 40
    }
}

但需要注意的是,clone()方法只会对实现了Cloneable接口的对象进行浅拷贝,而且需要在实现类中手动处理嵌套对象的拷贝。

 

Java深拷贝

1.Java深拷贝简介

所谓深拷贝就是相对浅拷贝而言的,在浅拷贝的基础上进一步进行深层拷贝。

 

2.Java深拷贝思想

深拷贝,它会创建一个全新的对象,同时递归地复制原始对象内部所有的嵌套对象。

深拷贝的主要思想可以总结如下:

  • 复制对象本身: 深拷贝首先会创建一个新对象,并将原始对象的字段值复制到新对象中。
  • 递归复制引用对象: 对于原始对象内部的引用类型字段,深拷贝会递归地复制引用对象,即创建新的嵌套对象副本。
  • 实现对象的独立性: 通过递归复制所有嵌套对象,深拷贝确保了复制后的对象及其内部所有引用对象都是完全独立的,互相之间的修改不会相互影响。

 

3.Java深拷贝优缺点

深拷贝优点在于能够确保对象及其内部所有嵌套对象的独立性,从而避免了共享引用对象可能带来的问题。

深拷贝的缺点是需要递归地遍历对象的所有嵌套引用,对每个引用对象都进行复制操作,这可能会导致深拷贝的性能较浅拷贝要差,因为需要复制更多的数据。

 

4.Java深拷贝实现

在Java中,实现深拷贝通常需要手动递归复制对象及其内部引用对象。

import java.io.*;

class Person implements Serializable {
    String name;
    Age age;

    public Person deepCopy() throws IOException, ClassNotFoundException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(bos);
        out.writeObject(this);

        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream in = new ObjectInputStream(bis);
        return (Person) in.readObject();
    }
}

class Age implements Serializable {
    int years;
}

public class DeepCopyExample {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Person person1 = new Person();
        person1.name = "Alice";
        person1.age = new Age();
        person1.age.years = 30;

        Person person2 = person1.deepCopy();

        System.out.println(person1.age.years); // Output: 30
        System.out.println(person2.age.years); // Output: 30

        person2.age.years = 40;

        System.out.println(person1.age.years); // Output: 30
        System.out.println(person2.age.years); // Output: 40
    }
}

上面,展示了通过实现Serializable接口来实现深拷贝的思想。

 

作者简介

陈睿|mikechen,10年+大厂架构经验,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

关注作者「mikechen」公众号,获取更多技术干货!

评论交流
    说说你的看法