Java中的深拷贝和浅拷贝的原理以及区别

createh55个月前 (02-01)技术教程31

深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是在Java编程中与对象复制有关的两个概念,表面上看二者都可以实现对象的复制,但是在复制的方式以及实现效果上却有着很大的区别,下面我们就来详细介绍一下在Java中关于深拷贝和浅拷贝的原理以及它们之间的区别。

什么是浅拷贝?

所谓的浅拷贝是指在复制一个对象的时候,新的对象会得到原有对象的一个副本,但是这只是对于对象引用的复制,而对象中的属性还是指向原对象中的内存地址。

在复制过程中,对于基本数据类型数据就会被直接复制,而对于引用数据类型来讲,则会复制其引用的地址,这也就意味着新的对象和原有的对象中的变量都是指向原有的同一块内存区域。这也就是说浅拷贝只是复制原有对象的字段,对于引用类型只是引用复制,修改引用类型的值还是会影响原有对象。

如下所示,给出一个简单的浅拷贝的实现。

class Person {
    String name;
    int age;
    
    // 构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

public class ShallowCopyExample {
    public static void main(String[] args) {
        Person person1 = new Person("John", 30);
        Person person2 = person1; // 浅拷贝:person2引用了person1的地址
        
        System.out.println("Before modification:");
        System.out.println("person1.name = " + person1.name + ", person2.name = " + person2.name);
        
        // 修改person2的属性
        person2.name = "Mike";
        
        System.out.println("After modification:");
        System.out.println("person1.name = " + person1.name + ", person2.name = " + person2.name);
    }
}

输出内容如下所示。

Before modification:
person1.name = John, person2.name = John
After modification:
person1.name = Mike, person2.name = Mike

从代码输出结果来看,因为person1和person2指向的是同一个内存地址,所以修改person2的值也会影响到person1。

什么是深拷贝?

深拷贝则是指在复制对象的时候,新的对象不仅会复制原有对象的基本数据类型的值,还会复制其应用对象数据类型并且会为其创建一个新的示例对象,并且将原有对象中的数据复制到新的对象中,所以对于深拷贝来讲,原有对象和新对象是两个完全独立的对象,因为它们所有的属性引用都指向了不同的内存空间中。

在深拷贝对象复制过程中,基本数据类型还是会被直接复制,而对于应用数据类型来讲,会创建新的对象,然后新对象也会复制原有对象中的内容,也就是说深拷贝不但复制了对象的属性而且还创建了新的引用,所以两个对象之间不会相互影响,如下所示。

class Person {
    String name;
    int age;
    
    // 构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // 深拷贝方法
    public Person deepCopy() {
        return new Person(this.name, this.age);
    }
}

public class DeepCopyExample {
    public static void main(String[] args) {
        Person person1 = new Person("John", 30);
        Person person2 = person1.deepCopy(); // 使用深拷贝
        
        System.out.println("Before modification:");
        System.out.println("person1.name = " + person1.name + ", person2.name = " + person2.name);
        
        // 修改person2的属性
        person2.name = "Mike";
        
        System.out.println("After modification:");
        System.out.println("person1.name = " + person1.name + ", person2.name = " + person2.name);
    }
}

输出结果如下所示。

Before modification:
person1.name = John, person2.name = John
After modification:
person1.name = John, person2.name = Mike

从上面输出结果来看,person1和person2是两个完全独立的对象,所以修改person2的值不会影响到person1的值。

总结

在实际开发中,选择使用浅拷贝还是深拷贝取决于具体的需求。对于简单的对象,浅拷贝通常能满足需求,而对于复杂对象或需要避免副作用的场景,深拷贝则更加合适。

相关文章

你还在用BeanUtils进行对象属性拷贝?

在做业务的时候,为了隔离变化,我们会将DAO查询出来的DO和对前端提供的DTO隔离开来。大概90%的时候,它们的结构都是类似的;但是我们很不喜欢写很多冗长的b.setF1(a.getF1())这样的代...

java对象深拷贝的三种实现方式,可避免循环引用导致的堆栈溢出

在java编程中,难免要对一个对象进行复制,复制分为深拷贝和浅拷贝。浅拷贝只复制对象本身,对于对象引用的其他对象不进行复制。 深拷贝则将对象与引用对象,全部进行拷贝。最简单的深拷贝就是自己new一个对...

Java常用的几种属性拷贝工具类使用总结

Java属性拷贝工具类使用总结对项目中经常使用的属性拷贝工具类进行总结:org.apache.commons.beanutils.BeanUtilsorg.apache.commons.beanuti...

④ JAVA IO—拷贝(java拷贝文件夹到另外一个文件夹)

一、 传统的IO1. 数据由磁盘拷贝到内核空间(DMA),再由内核空间拷贝到用户空间(JVM)2. 用户可能会对拷贝进来的数据进行操作3. 数据从用户空间拷贝到内核空间(JVM),再通过内核空间将数据...

Java中深拷贝、浅拷贝、赋值的区别?如何自己写个深拷贝工具类?

#头条创作挑战赛#为什么要了解JavaBean深拷贝的机制目前大家都在常用已经封装好的工具类,很少去深入了解多种实现方式;此处提出一种简单的实现原理,也是巩固Java中关于反射的用法和知识;目的:可以...

Java:深拷贝与浅拷贝(Cloneable接口)

文章目录1. Cloneable接口的介绍2. 浅拷贝的介绍和实例3. 深拷贝的介绍和实例1. Cloneable接口的介绍Cloneable是标记型的接口(空接口),它们内部都没有方法和属性, 实现...