Java中的深拷贝与浅拷贝

简介: 深拷贝和浅拷贝区别是什么?

数据分为基本数据类型和引用数据类型。基本数据类型:数据直接存储在栈中;引用数据类型:存储在栈中的是对象的引用地址,真实的对象数据存放在堆内存里。

浅拷贝:对于基础数据类型:直接复制数据值;对于引用数据类型:只是复制了对象的引用地址,新旧对象指向同一个内存地址,修改其中一个对象的值,另一个对象的值随之改变。

深拷贝:对于基础数据类型:直接复制数据值;对于引用数据类型:开辟新的内存空间,在新的内存空间里复制一个一模一样的对象,新老对象不共享内存,修改其中一个对象的值,不会影响另一个对象。

深拷贝相比于浅拷贝速度较慢并且花销较大。

深拷贝/浅拷贝分析案例


浅拷贝实现 Cloneable,深拷贝是通过实现 Serializable 读取二进制流

深拷贝实现:


首先Person 对象实现 Serializable 接口,然后自定义深拷贝方法 deepClone():

/**
 * 深拷贝
 * 
 * 注意:要实现序列化接口
 * @return
 */
public Person deepClone() {
    try {
        // 输出 (序列化)
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(this);
        // 输入 (反序列化)
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);
        Person person = (Person) ois.readObject();
        return person;
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

接下来验证一下深拷贝是否成功:

@Test
public void testPropotype() throws CloneNotSupportedException {
    Person person1 = new Person();
    person1.setAge(22);
    person1.setName("csp");
    // 初始化list 并为其加入数据
    person1.setList(new ArrayList<>());
    person1.getList().add("aaa");
    person1.getList().add("bbb");
    System.out.println("person1:"+person1);
    //-----------------------------浅拷贝-------------------------------
    //Person person2 = person1.clone();
    //-----------------------------深拷贝-------------------------------
    Person person2 = person1.deepClone();
    person2.setName("hzw");
    // 给peron2 中的list添加一条数据
    person2.getList().add("ccc");
    System.out.println("person2"+person2);
    System.out.println("person1:"+person1);
    boolean flag1 = person1 == person2;
    System.out.println("person1 和 person2 的 引用地址是否相同: " +  flag1);
    boolean flag2 = person1.getList() == person2.getList();
    System.out.println("person1 和 person2 的 list 引用地址是否相同: " +  flag2);
}

输出结果:

空参构造函数调用...
person1:Person{name='csp', age=22, list=[aaa, bbb]}
person2Person{name='hzw', age=22, list=[aaa, bbb, ccc]}
person1:Person{name='csp', age=22, list=[aaa, bbb]}
person1 和 person2 的 引用地址是否相同: false
person1 和 person2 的 list 引用地址是否相同: false

由结果可得出:深拷贝 person2 所得到的 list 内存地址和原来person1 中的内存地址是不同的,深拷贝成功!

相关文章
|
Java
Java的浅拷贝与深拷贝
Java的浅拷贝与深拷贝
174 0
|
Java Apache
Java中的深拷贝与浅拷贝
Java中的深拷贝与浅拷贝
161 0
|
8月前
|
人工智能 安全 Java
深入理解Java浅拷贝与深拷贝
本文深入探讨Java中浅拷贝与深拷贝的概念、实现方式及应用场景。浅拷贝通过`clone()`方法复制对象引用,修改新对象会影响原对象;深拷贝则创建完全独立的新对象,确保数据安全。文章通过代码示例讲解两种拷贝方式的实现,并分析其优缺点。同时,针对List类型提供浅拷贝和深拷贝的具体实现方法,帮助读者更好地理解和应用这两种技术。选择拷贝方式时需权衡对象复杂度、大小及操作安全性等因素。
460 2
|
Java
Java深拷贝和浅拷贝Map对象
Java深拷贝和浅拷贝Map对象
513 0
“深入探讨Java中的对象拷贝:浅拷贝与深拷贝的差异与应用“
“深入探讨Java中的对象拷贝:浅拷贝与深拷贝的差异与应用“
【JAVA面试题】什么是深拷贝?什么是浅拷贝?
【JAVA面试题】什么是深拷贝?什么是浅拷贝?
|
存储 Dubbo Java
一篇文章讲明白Java的深拷贝和浅拷贝
一篇文章讲明白Java的深拷贝和浅拷贝
130 0
|
Java
【java面试题】- java深拷贝和浅拷贝区别?什么是引用拷贝?
java深拷贝和浅拷贝区别?什么是引用拷贝?
173 0
|
Java
【Java】深拷贝和浅拷贝,Cloneable接口
【Java】深拷贝和浅拷贝,Cloneable接口
372 0
【Java】深拷贝和浅拷贝,Cloneable接口
Java 最常见的面试题:深拷贝和浅拷贝区别是什么?
Java 最常见的面试题:深拷贝和浅拷贝区别是什么?