克隆方法---javadoc

本文详细介绍了Java中Cloneable接口的使用方法及其注意事项,包括如何实现对象的拷贝,super.clone方法的作用,以及在实现Cloneable接口时可能遇到的问题。

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

clone
protected Object clone()throws CloneNotSupportedException

创建和返回一个对象的拷贝,拷贝的准确含义依赖于对象的类。

一般来说,对于任何对象x,
表达式x.clone() != x 是true,
表达式x.clone().getClass() == x.getClass()也是true,
但是这些都不是必须的。
虽然通常情况下,x.clone.equals(x)是true,但这也不是一个必须的要求。


通过super.clone获取返回对象。如果一个类和他的所有父类(除过Object)违背了这个规则,就会出现x.clone.getClass() == x.getClass();
通过该方法返回的对象应该独立于那个被克隆的对象。为了实现这种独立,很可能需要修改一个或多个通过对象super.clone返回的对象的域。通常,这意味要拷贝任何包含内部“深层结构”的可变对象,并且用指向新对象的引用替换原来指向这些对象的引用。如果类仅仅包含原始数据类型或者对不可变对象的引用,就不需要修改通过super.clone获得的拷贝对象。
Object的clone方法执行具体的克隆操作。首先,如果对象的类没有实现Cloneable接口,那么会抛出CloneNotSupportedException异常。需要注意的是所有的数组被视为实现了Cloneable接口。否则,这个方法创建这个对象的类的新实例,并且用与这个对象对应的所有域的内容初始化所有的域,因为是通过转让,所以字段的内容本身没有克隆。因此,这个方法对对象的“影子拷贝”,而不是“深度拷贝”。

Object本身没有实现Cloneable接口,所以说调用Object类对象的clone方法会在运行时抛出异常。

ps:关于clone的问题《effective java》进行了进一步阐述,具体应该注意一下几点:

[list]
[*]Cloneable接口没有提供任何方法,它做的事情就是:如果一个类实现了该接口,那么继承自Object的clone方法返回对象的逐域拷贝,否则抛出CloneNotSupportedException。
[*]显然对于实现了Cloneable接口的类,我们总希望它提供一个公有的clone方法,但通常情况下,除非该类的所有父类都提供了行为良好的clone方法,否则这是不可能的。
[*]作为另外一种形式的构造函数,你应该确保它不会伤害到原始的对象,并且正确建立起被克隆对象中的约束关系。(对于包含可变对象引用的类的对象应该特别注意,因为拿过来的引用是指向同一地址的对象,所以克隆对象和被克隆对象对他进行的修改会彼此影响)
[*]克隆复杂对象的另外一个方法是,先调用super.clone方法,然后将对象所有的域设置为空白状态,再通过调用高层的方法来重新产生对象的状态。
[*]不要在clone方法中调用clone对象的任何非final方法。
[/list]

注意: 对于实现cloneable接口的类,除过实现一个行为良好的共有clone方法外别无选择。否则最好的做法是,提供某些其他的途径来代替对象拷贝,或者干脆不提供这样的能力。对于非可变对象,反正状态是不会变的,拷贝对象和被拷贝对象并没有什么实质性的区别。由于Cloneable接口没有提供方法,所以我们可以通过拷贝函数,或者静态工厂来实现对象的拷贝。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值