clone方法

clone方法

方法的声明

protected native Object clone() throws CloneNotSupportedException;
  1. 这是一个本地native方法。(依赖本地方法实现创建对象,不同于new对象)
  2. throws CloneNotSupportedException是方法抛出异常的声明,这里我们先不管,后面异常的章节会讲解。

方法的作用

当你在程序中有这种需求,即希望:

  1. 得到一个和原先对象,完全独立的新对象。
  2. 成员仍和原先对象一致。

有这种做法时,普通的做法就是再new一个一模一样的,但学习clone方法后,你就可以用该方法来做这个事情了。Object类当中的clone方法的默认实现,就是得到一个独立的,和原先对象成员一致的新对象。

方法使用步骤

直接调用的话,肯定是有些问题的,这里我们就来研究一下clone方法的使用步骤:

  1. 第一步,修改访问权限
    clone()方法的访问权限是protected。让一个类自身克隆自身,一般都没有多大意义,所以建议在子类中重写方法访问权限。所以为了能够在类的外部调用该类的clone方法,就需要在该类中重写clone方法的访问权限。
  2. 第二步,修改返回值类型,从Object改为自身类型
    很显然Object当中的克隆方法的默认实现,只会得到一个一模一样且独立的对象,肯定不可能改变对象的类型。建议在子类方法中重写这个返回值类型。
  3. 第三步,实现接口 java.lang.Cloneable
    一个类想要做克隆操作,必须要先实现一个接口 java.lang.Cloneable,表示该类允许进行克隆。
    如果一个类没有实现接口java.lang.Cloneable,又要强行进行克隆操作,就会抛出异常CloneNotSupportedException。
    Cloneable接口是一个空接口,里面没有任何内容。

克隆使用中的细节问题

Cloneable接口

Cloneable接口是一个空接口,里面没有任何内容。那么让类去实现一个空接口,有什么意义呢?

实现空接口虽然没有得到任何成员,但这个类的数据类型就发生了一些变化。

让这个类从原先不是这个接口的子类,变成了接口的子类。一旦成为接口的子类,就可以使用instanceof关键字进行类型的判断,判断到底是否该接口。从而就可以根据不同的情况,做出不同的处理。

像Cloneable这种没有声明定义任何成员的,一个空接口,它其实就起到一个标记的作用,称之为"标记接口"。

被Cloneable标记的类是允许做克隆操作的,反之不允许。JDK中的标记接口,以后还会见到。

创建对象的方式

clone方法是一种新的创建对象的方式,和new对象的方式是平行的关系,是独立的关系。

调用clone方法得到对象的过程,是依赖于本地方法实现的,不会去调用构造器。

方法体的重写

在进行克隆操作时,正常情况下,我们使用Object类当中的默实现就足够了,不需要重写实现。但假如你真的有需求,对于某个对象的引用x,JDK文档中也规定了一些重写的原则:

  1. x.clone() != x 为 true
  2. x.clone().getClass() == x.getClass() 一般也为true
  3. x.clone().equals(x) 一般情况下也为true

上述规定告诉我们:

  1. 克隆必须是一个新的独立的对象
  2. 克隆最好不要改变数据类型,除非你真的有需要。
  3. 克隆后的两个对象调用equals方法,应该返回true。前提是,必须按照成员变量的取值重写equals方法。

深度克隆

如果类中有引用数据类型的成员变量,那么clone方法的使用就要格外注意了:

  1. Java当中,Object类的clone方法的默认实现是完全直接拷贝一份成员变量。
    1. 对于基本数据类型的成员变量来说,没有任何问题,直接拷贝值。
    2. 但对于引用数据类型而言,拷贝的是引用。这意味着克隆后的引用和原先的引用指向同一个对象。
  2. 这样的话,使用任何一个引用去修改对象的状态,都会互相影响,这样的两个对象就不是完全独立的了。

浅克隆:像以上Object类当中的clone方法的实现,直接拷贝一份成员变量,引用数据类型克隆后,两个引用指向同一个对象,这样的克隆我们称之为"浅克隆"。

深克隆:对应的,如果能够让引用数据类型成员变量之间也能相互独立,克隆后获取真正独立的两个对象。我们称之为"深克隆"。

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值