浅拷贝、深拷贝

 浅拷贝、深拷贝
浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。
深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。
举例来说更加清楚:对象A1中包含对B1的引用,B1中包含对C1的引用。浅拷贝A1得到A2,A2 中依然包含对B1的引用,B1中依然包含对C1的引用。
深拷贝则是对浅拷贝的递归,深拷贝A1得到A2,A2中包含对B2(B1的copy)的引用,B2 中包含对C2(C1的copy)的引用。
    若不对clone()方法进行改写,则调用此方法得到的对象即为浅拷贝


 当然我们还有一种深拷贝方法,就是将对象串行化:private static final long serialVersionUID = 1L;

但是串行化却很耗时,在一些框架中,我们便可以感受到,它们往往将对象进行串行化后进行传递,耗时较多。

package org.javacore.base.copy;


/**
 * @author Robin
 * @since 2016-09-19 13:53:51
 *  深拷贝与浅拷贝
 */
class Family implements Cloneable{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    /**
     * 深拷贝
     * @return
     */
    @Override
    public Object clone() {
        Object o = null;
        try {
            o = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return o;
    }
}
class Student implements Cloneable{
    private String name;
    private Family family;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Family getFamily() {
        return family;
    }

    public void setFamily(Family family) {
        this.family = family;
    }

    /**
     * 浅拷贝 对其对象的引用却没有拷贝
     * @return
     * @throws CloneNotSupportedException
     */
//    @Override
//    protected Object clone() throws CloneNotSupportedException {
//        return super.clone();
//    }

    /**
     * 深拷贝
     */
    @Override
    protected Object clone() {
        Student o = null;
        try {
            o = (Student)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        o.family = (Family) family.clone();
        return o;
    }
}

public class CopyT {
    public static void main(String[] args) throws CloneNotSupportedException {
        Family family = new Family();
        family.setName("Jeff Family");
        Student student1 = new Student();
        student1.setFamily(family);
        student1.setName("Jeff");

        Student student2 = (Student) student1.clone();
        student2.setName("Jeff2");
        student2.getFamily().setName("Jeff2 Family");
        System.out.println(student1.getName() + " " + student1.getFamily().getName());
        System.out.println(student2.getName() + " " + student2.getFamily().getName());
    }
}



### Java 中浅拷贝深拷贝的区别及用法 #### 1. 浅拷贝 (Shallow Copy) 浅拷贝是指创建一个新的对象,这个新对象会复制原对象中的基本数据类型字段值以及引用类型的内存地址。这意味着,在浅拷贝的情况下,如果原始对象包含其他对象的引用,则这些引用会被简单地复制到新的对象中,而不是重新创建被引用的对象。 在 Java 中可以通过 `Object` 类的 `clone()` 方法来实现浅拷贝[^1]。需要注意的是,默认情况下,`clone()` 只能完成浅拷贝操作。下面是一个浅拷贝的例子: ```java class Person implements Cloneable { String name; int age; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public class Main { public static void main(String[] args) throws CloneNotSupportedException { Person original = new Person(); original.name = "Alice"; original.age = 25; Person copied = (Person) original.clone(); System.out.println(copied.name); // 输出 Alice System.out.println(copied.age); // 输出 25 } } ``` 上述代码展示了如何通过重写 `clone()` 方法来进行浅拷贝[^4]。 #### 2. 深拷贝 (Deep Copy) 深拷贝不仅复制了对象本身,还递归地复制了该对象所引用的所有子对象。因此,即使修改了原始对象的内容,也不会影响到副本对象的状态。这使得深拷贝更加安全但也更耗费资源和时间。 要实现深拷贝,可以采用序列化的方式或者手动逐级克隆每一个成员变量及其内部结构[^3]。以下是利用序列化的例子: ```java import java.io.*; class Address implements Serializable { String city; } class Employee implements Serializable, Cloneable { String name; transient Address address; private Object readResolve() throws ObjectStreamException { this.address = new Address(); this.address.city = "New York"; return this; } @Override protected Object clone() throws CloneNotSupportedException { 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 ois.readObject(); } catch (IOException | ClassNotFoundException e) { throw new RuntimeException(e); } } } public class DeepCopyExample { public static void main(String[] args) throws Exception{ Employee empOriginal = new Employee(); empOriginal.name = "John Doe"; Address addr = new Address(); addr.city = "Los Angeles"; empOriginal.address = addr; Employee deepCopiedEmp = (Employee)empOriginal.clone(); System.out.println(empOriginal.name.equals(deepCopiedEmp.name)); // true System.out.println(empOriginal.address == deepCopiedEmp.address); // false } } ``` 此示例说明了如何借助序列化机制执行真正的深拷贝过程。 #### 3. 主要差异对比 | 特性 | 浅拷贝 | 深拷贝 | |-------------------|----------------------------------|--------------------------------| | **定义** | 复制基础数据类型并共享引用 | 完全独立的新实例 | | **性能开销** | 较低 | 高 | | **适用场景** | 数据量较小或无需完全隔离的情况 | 要求严格分离的数据处理 | #### 4. 总结 当仅需快速复制少量数据而不关心后续更改时可选用浅拷贝;而对于那些需要保持绝对一致性的复杂数据结构则应考虑使用深拷贝
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值