深/浅拷贝

文章讲述了在Java中如何对自定义的Person对象进行克隆,包括实现Cloneable接口,重写Object的clone方法。通过示例展示了浅拷贝和深拷贝的区别:浅拷贝仅复制对象本身,而深拷贝则递归复制对象内的引用对象,确保独立性。

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

现在有一个我们自定义的Person对象,如何去克隆这个对象?

class Person{
    public int id;

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                '}';
    }
}
public class Test2 {
    public static void main(String[] args) {
        Person person1 = new Person();
    }
}

1.给自定义的Person类实现Cloneable接口

class Person implements Cloneable{
    public int id;

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

 2.重写Object克隆方法

class Person implements Cloneable{
    public int id;

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

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

3. 声明异常,再进行强制类型转换

public class Test2 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person();
        Person person2 = (Person) person1.clone();
    }
}

clone方法的返回值是Object,因此需要强制类型转换一下

浅拷贝

现在给这个 这个Person对象再添加一个NameAndMoney属性

class NameAndMoney{
    String name;
    double m;

    public NameAndMoney(String name, double m) {
        this.name = name;
        this.m = m;
    }

    @Override
    public String toString() {
        return "NameAndMoney{" +
                "name='" + name + '\'' +
                ", m=" + m +
                '}';
    }
}
class Person implements Cloneable{
    public int id;
    public NameAndMoney nameAndMoney;

    public Person(int id, String name,double m) {
        this.id = id;
        this.nameAndMoney = new NameAndMoney(name,m);
    }

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

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

浅拷贝:直接使用克隆方法

public class Test2 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person(1,"张三",9999);
        Person person2 = (Person) person1.clone();
        person2.id=2;
        person2.nameAndMoney.name="李四";
        person2.nameAndMoney.m=8888;
        System.out.println(person1);
        System.out.println(person2);
    }
}

可以发现person2的改变会引起person1的变化,这就是浅拷贝,它只是把person1里面的内容完全复制了 

  也就是说只要0x11这个引用里面的内容发生改变,person1和person2都会发生改变

深拷贝

给NameAndMoney同样实现Cloneable接口,重写clone方法,再重写我们Person中的clone方法

class NameAndMoney implements Cloneable{
    String name;
    double m;

    public NameAndMoney(String name, double m) {
        this.name = name;
        this.m = m;
    }

    @Override
    public String toString() {
        return "NameAndMoney{" +
                "name='" + name + '\'' +
                ", m=" + m +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Person implements Cloneable{
    public int id;
    public NameAndMoney nameAndMoney;

    public Person(int id, String name,double m) {
        this.id = id;
        this.nameAndMoney = new NameAndMoney(name,m);
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person tmp = (Person) super.clone();
        tmp.nameAndMoney = (NameAndMoney)this.nameAndMoney.clone();
        return tmp;
    }

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

 关键代码

 @Override
    protected Object clone() throws CloneNotSupportedException {
        Person tmp = (Person) super.clone();
        tmp.nameAndMoney = (NameAndMoney)this.nameAndMoney.clone();
        return tmp;
    }

 

 总结:

浅拷贝:浅克隆在克隆对象时,会直接复制引用类型的地址,导致克隆前后该引用类型指向的是同一个对象。深克隆会克隆引用类型所指的对象,并赋予它一个新的地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值