首页 > 编程语言 >Java中的深拷贝和浅拷贝

Java中的深拷贝和浅拷贝

时间:2024-12-06 21:57:06浏览次数:5  
标签:city Java name person2 Person person1 address 拷贝

在Java中,浅拷贝(Shallow Copy)和深拷贝(Deep Copy)是两种不同的对象复制方式。它们在处理对象内部引用类型的属性时表现不同。以下是对这两种拷贝方式的详细解释,并附有相应的代码示例。

 浅拷贝(Shallow Copy)

 定义

浅拷贝会创建一个新对象,但对于对象内部的引用类型属性,仍然复制其引用而不是创建一个新的独立对象。这意味着新对象和原对象共享这些引用类型的属性。

 实现方式

实现Cloneable接口并重写clone()方法。

使用拷贝构造函数。

 示例代码

// 定义一个类,包含引用类型属性
class Address {
    String city;

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

    @Override
    public String toString() {
        return city;
    }
}

class Person implements Cloneable {
    String name;
    Address address;

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

    // 重写clone方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); // 浅拷贝
    }

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

public class ShallowCopyExample {
    public static void main(String[] args) {
        try {
            Address addr = new Address("Beijing");
            Person person1 = new Person("Alice", addr);
            Person person2 = (Person) person1.clone();

            System.out.println("Before modification:");
            System.out.println("person1: " + person1);
            System.out.println("person2: " + person2);

            // 修改person2的地址
            person2.address.city = "Shanghai";

            System.out.println("\nAfter modification:");
            System.out.println("person1: " + person1); // person1的地址也被修改
            System.out.println("person2: " + person2);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

输出结果
Before modification:
person1: Person{name='Alice', address=Beijing}
person2: Person{name='Alice', address=Beijing}

After modification:
person1: Person{name='Alice', address=Shanghai}
person2: Person{name='Alice', address=Shanghai}

说明

在上述代码中,person1和person2共享同一个Address对象。当person2的address.city被修改时,person1的address.city也随之改变,这就是浅拷贝的特性。

 深拷贝(Deep Copy)

 定义

深拷贝会创建一个新对象,并且递归地复制对象内部的所有引用类型属性,使得新对象与原对象完全独立。

 实现方式

 实现Cloneable接口并重写clone()方法,在clone()方法中递归地克隆所有引用类型属性。

 使用拷贝构造函数。

 使用序列化(Serialization)。

 示例代码

// 定义一个类,包含引用类型属性,并实现深拷贝
class Address implements Cloneable {
    String city;

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

    // 重写clone方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return city;
    }
}

class Person implements Cloneable {
    String name;
    Address address;

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

    // 重写clone方法,实现深拷贝
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person cloned = (Person) super.clone();
        cloned.address = (Address) address.clone(); // 递归克隆引用类型属性
        return cloned;
    }

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

public class DeepCopyExample {
    public static void main(String[] args) {
        try {
            Address addr = new Address("Beijing");
            Person person1 = new Person("Alice", addr);
            Person person2 = (Person) person1.clone();

            System.out.println("Before modification:");
            System.out.println("person1: " + person1);
            System.out.println("person2: " + person2);

            // 修改person2的地址
            person2.address.city = "Shanghai";

            System.out.println("\nAfter modification:");
            System.out.println("person1: " + person1); // person1的地址不会被修改
            System.out.println("person2: " + person2);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

输出结果
Before modification:
person1: Person{name='Alice', address=Beijing}
person2: Person{name='Alice', address=Beijing}

After modification:
person1: Person{name='Alice', address=Beijing}
person2: Person{name='Alice', address=Shanghai}

说明

在上述代码中,person1和person2拥有独立的Address对象。当person2的address.city被修改时,person1的address.city保持不变,这就是深拷贝的特性。

 总结

 浅拷贝适用于对象内部没有引用类型属性,或者可以接受共享引用的情况。

 深拷贝适用于需要完全独立的对象副本,确保原对象和新对象之间没有引用共享的情况。

 

标签:city,Java,name,person2,Person,person1,address,拷贝
From: https://blog.csdn.net/lxsxjsj/article/details/144301187

相关文章

  • JavaSwing JSlider
    try{BeautyEyeLNFHelper.frameBorderStyle=BeautyEyeLNFHelper.FrameBorderStyle.osLookAndFeelDecorated;//UIManager.put("RootPane.setupButtonVisible",false);org.jb2011.lnf.beautyeye.BeautyEyeLNFHelpe......
  • JavaSwing JProcessBar
    try{BeautyEyeLNFHelper.frameBorderStyle=BeautyEyeLNFHelper.FrameBorderStyle.osLookAndFeelDecorated;//UIManager.put("RootPane.setupButtonVisible",false);org.jb2011.lnf.beautyeye.BeautyEyeLNFHelpe......
  • JavaSwing JRadioButton
    try{BeautyEyeLNFHelper.frameBorderStyle=BeautyEyeLNFHelper.FrameBorderStyle.osLookAndFeelDecorated;//UIManager.put("RootPane.setupButtonVisible",false);org.jb2011.lnf.beautyeye.BeautyEyeLNFHelpe......
  • Java中的向上转型与向下转型
    文章目录向上转型(Upcasting)定义工作原理用途注意事项向下转型(Downcasting)定义工作原理用途注意事项示例结果与解释向上转型(Upcasting)定义概念:向上转型是指将子类对象赋值给父类类型的引用变量。转换类型:隐式转换,不需要显式的强制转换符号。工作原理......
  • JavaSwing JCheckBox
    try{BeautyEyeLNFHelper.frameBorderStyle=BeautyEyeLNFHelper.FrameBorderStyle.osLookAndFeelDecorated;//UIManager.put("RootPane.setupButtonVisible",false);org.jb2011.lnf.beautyeye.BeautyEyeLNFHelpe......
  • java毕业设计-基于springboot+vue的企业员工hr信息管理平台设计和实现,基于springboot
    博主介绍:✌️码农一枚,专注于大学生项目实战开发、讲解和毕业......
  • Java笔记——泛型
    一、什么是泛型泛型是在JDK5中引入的特性,可以在编译阶段约束操作的数据类型,并进行检查,泛型的格式为<数据类型>,只支持引用数据类型。二、泛型的作用在没有泛型之前,Java程序员会使用Object类型来实现‘通用’的容器类,例如:ArrayListlist=newArrayList();......
  • Java笔记——集合3-ArrayList和LinkedList集合
    一、ArrayList集合ArrayList集合的方法大多都继承于List和Collection,但ArrayList集合有自己独特的底层原理:①用空参创建的集合,在底层创建的是一个默认长度为0的数组②添加第一个元素时,底层会创建一个新的长度为10的数组③集合存满时,会自动扩容1.5倍长度④如果一次性添加多......
  • java接口测试利器【postman】
    怎样使用postman一、了解postman1.postman?—— 软件测试用来做接口测试的工具。2.下载postman—— https://www.getpostman.com/(官方下载)3.postman的界面二、用postman工具测试创建一个新的请求:打开Postman应用,创建一个工作区。点击“New”按钮,选择“Reques......
  • 一周掌握 Java 入门知识
    学习目标:提示:这里可以添加学习目标例如:一周掌握Java入门知识学习内容:提示:这里可以添加要学的内容例如:搭建Java开发环境掌握Java基本语法掌握条件语句掌握循环语句学习时间:提示:这里可以添加计划学习的时间例如:周一至周五晚上7点—晚上9点周六上午9点......