Java:浅克隆与深克隆解析

本文通过实例详细解析了Java中的浅克隆与深克隆,展示了它们在对象复制过程中的不同表现,尤其强调了引用类型在复制过程中的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

浅克隆

Address.java

public class Address implements Cloneable{

    private String address;

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

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

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Address{" +
                "address='" + address +
                '}';
    }
}
Customer.java
public class Customer implements Cloneable{

    private int age;
    private String name;
    private Address address;
    
    //  实现克隆方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
    
    @Override
    public String toString() {
        return "Customer{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", address=" + address.toString() +
                '}';
    }
}

下面是测试方法以及结果

public class CloneMain {

    public static void main(String[] args) {

        Address address = new Address("狗窝");

        Customer customer = new Customer();
        customer.setAge(18);
        customer.setName("二狗子");
        customer.setAddress(address);
        customer.toString();
        try {
            Customer clone = (Customer) customer.clone();
            clone.setAge(14);
            clone.setName("三驴子");
            clone.getAddress().setAddress("驴棚");

            System.out.println("********************customer********************");
            System.out.println(customer.toString());
            System.out.println("********************clone********************");
            System.out.println(clone.toString());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

    }

}
********************customer********************
Customer{age=18, name='二狗子', address=Address{address='驴棚}}
********************clone********************
Customer{age=14, name='三驴子', address=Address{address='驴棚}}

BUILD SUCCESSFUL in 692ms
很明显,clone后基本数据类型没有收到干扰,引用类型的把之前的数据都改了,二狗子失去了狗窝!这是浅复制的弊端,引用类型指向的是同一个对象!

浅复制

深复制

只需重写Customer.java的clone方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Customer customer = (Customer) super.clone();
        customer.setAddress((Address) address.clone());
        return customer;
    }
执行结果
> Task :proxy:CloneMain.main()
********************customer********************
Customer{age=18, name='二狗子', address=Address{address='狗窝}}
********************clone********************
Customer{age=14, name='三驴子', address=Address{address='驴棚}}

BUILD SUCCESSFUL in 448ms

结果很明显,二狗子和三驴子不是同一个窝了!clone方法把对象也在堆中clone了一份,引用各指向各的对象!
深复制

总结

Java的数据类型分为基本数据类型和引用数据类型,这两种类型传递时会有值传递和引用传递两种!
基本数据类型的变量指向虚拟机栈,引用类型的变量指向堆。
浅克隆不能实现内存上的克隆,即不能实现真正意义上的对象“复制”,克隆后的内部引用与之前对象的引用指向同一块内存。深克隆要求类中所有的类都要实现Cloneable接口并重写clone方法!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值