1、含义

浅拷贝:一个对象在被拷贝后,两个对象完全相同,指向的地址一致,修改其中一个对象中的变量,另一个对象也相应发生改变。

深拷贝:一个对象在被拷贝后,两个对象相同,但相互独立,指向的地址不同,修改其中一个对象中的变量,另一个对象不会发生改变。

2、实际案例

2.1 浅拷贝

在示例中,我们将对象person01直接赋值给变量声明person02,在赋值过程中,实际上是把person01指向的地址给person02指向,所以person01和person02两个对象指向的地址一致。

所以在浅拷贝中,更改一个对象的变量后,指向同样地址的对象中的变量自然也发生了改变。

示例代码

运行结果

2.1 深拷贝

在示例中,我们分别创建了person01和person02两个对象,并将person01中的变量的值赋值给person02中的变量,在这个过程中person01和person02分别指向了两个不同的地址,并进行赋值操作,在后面对person01进行更改后,对person02并无影响,就是因为两个对象的指向不同。

通俗易懂的来说,要复制的对象是person01,我们先创建同属于Person类的person02,再将person01的属性值赋值给person02,这就是深拷贝。

示例代码

运行结果

3、深拷贝的三种方式

3.1 直接创建对象,再赋值

3.2重写clone方法(也可以自定义其它方法)

3.3 通过序列化实现深拷贝

4、注意事项

其实在Person person = new Person();中,这也是一次浅拷贝,将右边创建出来的对象地址赋给左边的变量声明。
在深拷贝过程中要注意,拷贝对象中有无类属性变量,有的话,该变量也要做相应的深拷贝处理。

5、示例代码


import java.io.*;

public class Example03 {

    public static void main(String[] args) {

//        java对象的浅拷贝与深拷贝
        System.out.println("--------------------------------浅拷贝------------------");
        shallowCopy();
        System.out.println("----------------------------直接创建对象,再赋值-----------");
        deepCopy01();
        System.out.println("-------------------------------重写clone方法-------------");
        deepCopy02();
        System.out.println("---------------------------通过序列化实现深拷贝-------------");
        deepCopy03();

    }

    public static void shallowCopy() {

        Person person01 = new Person();
        person01.name = "小明";
        person01.age = 18;
        Person person02 = person01;
        System.out.println("person01:" + person01);
        System.out.println("person02:" +person02);
        System.out.println("-----------对person01的name字段进行更改后");
        person01.name = "小红";
        System.out.println("person01:" + person01);
        System.out.println("person02:" +person02);

    }

//    直接创建对象,再赋值
    public static void deepCopy01() {

        Person person01 = new Person();
        person01.name = "小明";
        person01.age = 18;
        Person person02 = new Person();
        person02.name = person01.name;
        person02.age = person01.age;
        System.out.println("person01:" + person01);
        System.out.println("person02:" +person02);
        System.out.println("-----------对person01的name字段进行更改后");
        person01.name = "小红";
        System.out.println("person01:" + person01);
        System.out.println("person02:" +person02);

    }

//    重写clone方法(也可以自定义其它方法)
    public static void deepCopy02() {

        Person person01 = new Person();
        person01.name = "小明";
        person01.age = 18;
        Person person02 = person01.clone();
        person02.name = person01.name;
        person02.age = person01.age;
        System.out.println("person01:" + person01);
        System.out.println("person02:" +person02);
        System.out.println("-----------对person01的name字段进行更改后");
        person01.name = "小红";
        System.out.println("person01:" + person01);
        System.out.println("person02:" +person02);

    }

//    通过序列化实现深拷贝
    public static void deepCopy03() {

        Person person01 = new Person();
        person01.name = "小明";
        person01.age = 18;
        Person person02 = person01.deepSerializable();
        person02.name = person01.name;
        person02.age = person01.age;
        System.out.println("person01:" + person01);
        System.out.println("person02:" +person02);
        System.out.println("-----------对person01的name字段进行更改后");
        person01.name = "小红";
        System.out.println("person01:" + person01);
        System.out.println("person02:" +person02);

    }



}
class Person implements Serializable {
    public String name;
    public int age;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    @Override
    public Person clone() {
        Person person = new Person();
        person.name = this.name;
        person.age = this.age;
        return person;
    }

    public Person deepSerializable() {

        try {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(this);
            objectOutputStream.flush();
            objectOutputStream.close();
            byteArrayOutputStream.close();

            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
            ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
            return (Person) objectInputStream.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;

    }
}

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐