clone()、浅复制、深复制

  • 什么是clone方法?clone方法有什么作用?

首先要明白一个基本点:基本数据类型的传递是值传递,其他类型的传递是引用传递。

Person person = new Person();
Person newPerson = person;
System.out.println(person);     // com.question.clone.Person@1b6d3586
System.out.println(newPerson);  // com.question.clone.Person@1b6d3586

上述代码证明,单纯得将一个对象赋值给另一个对象,实际上是将引用地址赋值给了新的对象,它们指向的是同一片内存区域,因此当对newPerson的属性进行操作时,同样会改变person属性,这显然是不合理的。

为了规避这一现象,Java提供了clone方法。具体操作如下:

  • 实现clone的类首先需要继承Cloneable接口(Cloneable接口实质是一个标识接口,没有任何的接口方法)
  • 在类中重写Object类中的clone()方法
  • 在clone()方法中调用super.clone()。无论clone类继承结构是什么,super.clone()会直接或间接java.lang.Object类中的clone()方法
  • 把浅复制的引用指向原型对象新的克隆体。
浅复制和深复制
  • 浅复制:被复制的对象的所有变量都含有与原来对象一样的值(这部分值在内存中开辟了新空间),而其他对象的引用仍指向原来的对象。换言之,浅复制仅仅复制了所考虑对象的引用,而不赋值它所引用的对象。
  • 深复制:被复制的对象的所有变量都含有与原来对象一样的值,除去那些引用对其他对象的变量(因此如果要完整得实现克隆,非基本数据类型的属性也要实现Cloneable接口并重写clone方法),那些引用其他对象的变量将指向被复制的新对象,而不知原来那些被引用的对象。换言之,深复制把浅复制的对象所引用的对象都复制了一遍。

在这里插入图片描述

代码实现
public class Person implements Cloneable{

    private String name;
    Money m;
    int age;

    public Person(){

    }

    public Person(String name, int age){
        this.name = name;
        m = new Money();
        this.age = 18;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person person = (Person) super.clone();     // 浅复制:克隆Person对象
        person.m = (Money) this.m.clone();  // 深复制:克隆Person对象中引用指向对象
        return person;
    }
}

class Money implements Cloneable{

    double money = 12.0;

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

public static void main(String[] args) throws CloneNotSupportedException {
    Person person1 = new Person("曹操", 18);
    Person person2 = (Person) person1.clone();

    System.out.println(person1.m);  // com.question.clone.Money@1b6d3586
    System.out.println(person2.m);  // com.question.clone.Money@4554617c

    person2.m.money = 1000.0;
    person2.age = 24;

    System.out.println(person1.m.money);    // 12.0
    System.out.println(person2.m.money);    // 1000.0

    System.out.println(person1.age);	// 18
    System.out.println(person2.age);	// 24
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值