Java中深拷贝,浅拷贝与引用拷贝的区别是什么

发布时间:2022-08-23 14:00:14 作者:iii
来源:亿速云 阅读:177

Java中深拷贝、浅拷贝与引用拷贝的区别是什么

在Java编程中,对象的拷贝是一个常见的操作。拷贝可以分为深拷贝、浅拷贝和引用拷贝三种类型。理解这三种拷贝方式的区别对于编写高效、安全的代码至关重要。本文将详细探讨这三种拷贝方式的定义、实现方法以及它们之间的区别。

1. 引用拷贝

1.1 定义

引用拷贝是指将一个对象的引用赋值给另一个变量。这意味着两个变量指向同一个对象,任何对其中一个变量的修改都会影响到另一个变量。

1.2 示例代码

class Person {
    String name;
    int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

public class ReferenceCopyExample {
    public static void main(String[] args) {
        Person person1 = new Person("Alice", 25);
        Person person2 = person1; // 引用拷贝

        person2.age = 30;

        System.out.println(person1.age); // 输出 30
    }
}

1.3 分析

在上面的代码中,person2person1 的引用拷贝。因此,修改 person2 的属性会影响到 person1

2. 浅拷贝

2.1 定义

浅拷贝是指创建一个新对象,然后将原对象的非静态字段复制到新对象中。如果字段是基本类型,则复制其值;如果字段是引用类型,则复制其引用。

2.2 实现方法

在Java中,可以通过实现 Cloneable 接口并重写 clone() 方法来实现浅拷贝。

2.3 示例代码

class Address {
    String city;

    Address(String city) {
        this.city = city;
    }
}

class Person implements Cloneable {
    String name;
    int age;
    Address address;

    Person(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

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

public class ShallowCopyExample {
    public static void main(String[] args) {
        try {
            Address address = new Address("New York");
            Person person1 = new Person("Alice", 25, address);
            Person person2 = (Person) person1.clone(); // 浅拷贝

            person2.age = 30;
            person2.address.city = "Los Angeles";

            System.out.println(person1.age); // 输出 25
            System.out.println(person1.address.city); // 输出 Los Angeles
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

2.4 分析

在上面的代码中,person2person1 的浅拷贝。person2age 字段是基本类型,因此修改 person2age 不会影响到 person1。然而,address 字段是引用类型,因此修改 person2address 会影响到 person1

3. 深拷贝

3.1 定义

深拷贝是指创建一个新对象,并递归地复制原对象的所有字段,包括引用类型的字段。这意味着深拷贝后的对象与原对象完全独立,修改其中一个对象不会影响到另一个对象。

3.2 实现方法

在Java中,可以通过递归调用 clone() 方法或使用序列化与反序列化来实现深拷贝。

3.3 示例代码

import java.io.*;

class Address implements Serializable {
    String city;

    Address(String city) {
        this.city = city;
    }
}

class Person implements Serializable {
    String name;
    int age;
    Address address;

    Person(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public Person deepCopy() {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(this);

            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            return (Person) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }
}

public class DeepCopyExample {
    public static void main(String[] args) {
        Address address = new Address("New York");
        Person person1 = new Person("Alice", 25, address);
        Person person2 = person1.deepCopy(); // 深拷贝

        person2.age = 30;
        person2.address.city = "Los Angeles";

        System.out.println(person1.age); // 输出 25
        System.out.println(person1.address.city); // 输出 New York
    }
}

3.4 分析

在上面的代码中,person2person1 的深拷贝。person2ageaddress 字段都是独立的,因此修改 person2ageaddress 不会影响到 person1

4. 深拷贝、浅拷贝与引用拷贝的区别

4.1 引用拷贝 vs 浅拷贝 vs 深拷贝

4.2 适用场景

4.3 性能比较

5. 总结

在Java中,深拷贝、浅拷贝和引用拷贝是三种不同的对象拷贝方式。理解它们的区别对于编写高效、安全的代码至关重要。引用拷贝是最简单的拷贝方式,但可能会导致意外的副作用。浅拷贝适用于对象结构简单的场景,而深拷贝适用于对象结构复杂且需要独立修改的场景。在实际开发中,应根据具体需求选择合适的拷贝方式。

6. 参考资料


通过本文的详细讲解,相信读者已经对Java中的深拷贝、浅拷贝和引用拷贝有了深入的理解。在实际开发中,合理选择拷贝方式可以有效避免潜在的问题,提高代码的质量和性能。

推荐阅读:
  1. python列表--浅拷贝与深拷贝的区别
  2. 深拷贝&浅拷贝

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java

上一篇:怎么用filebeat收集多个域名网站日志并存储到不同es索引库

下一篇:goodnotes如何使用

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》