public class Color {
String color;
Color(String color)
{
this.color=color;
}
}
public class ColoredCircle {
int x;
Color color;
ColoredCircle(int x, Color color)
{
this.x=x;
this.color=color;
}
public Object testClone()
{
Color c = new Color(this.color.color);
ColoredCircle cc1 = new ColoredCircle(this.x, c);
return cc1;
}
}
在上面提到的ColoredCircle类中,我们有一个名为testClone()的方法,它与Deep Cloning完全相同。 现在我很困惑,有必要实现Cloneable克隆吗? 以上程序是一种深度克隆吗?
答案 0 :(得分:2)
需要实现Cloneable
接口才能调用Object.clone()
不抛出异常。 (这是Cloneable
的全部目的。)
您没有使用Object.clone()
。因此,实施Cloneable
与否是没有效果的。它与您的方法调用无关。您的方法可以调用testClone()
,最多可以调用super.clone()
。或者您的方法可能被称为clone()
,并且无法使用super.clone()
。重要的是你没有使用Object.clone()
。
使用Object.clone()
的优点是它返回的对象与调用它的对象具有完全相同的运行时类。另一方面,您的方法始终创建一个新的ColoredCircle
对象。因此,当您的testClone()
方法在子类中继承时,它仍将创建ColoredCircle
,而不是该子类的实例。如果您的方法调用super.clone()
,它将能够获取当前实例的任何子类的实例。
答案 1 :(得分:1)
是否有必要将Cloneable
实施为克隆?是.clone()方法具有受保护的访问修饰符,其中包含以下Javadoc说明: -
此方法创建此对象的类的新实例,并使用该对象的相应字段的内容初始化其所有字段,就像通过赋值一样;这些字段的内容本身不会被克隆。因此,此方法执行此对象的shallow copy
,而不是deep copy
操作。
您的方法testClone
虽然在克隆行为中可能是正确的,但本身不是可克隆对象。可克隆对象必须实现Cloneable
接口,并且最好具有clone()
的公共访问权限它可以在课外使用。
有人在课堂上重读testClone()
方法的重要性。
答案 2 :(得分:0)
Cloneable
是一个标记界面。它不包含任何方法。
问题是clone
类中定义了Object
方法。由于所有类都实现了Object
类,这意味着所有类都有clone
方法。但是,并非所有对象都支持它。他们中的一些人只会抛出一个CloneNotSupportedException
。但是这个克隆方法是一个native
方法,因此这个方法的确切行为在java源代码中是不可见的。所以,它缺乏透明度。
Cloneable
界面可以帮助我们识别哪些类是可克隆的,哪些不是。按照惯例,未实现Cloneable
的类将抛出CloneNotSupportedException
。
注意: clone
方法也标记为protected
。因此,覆盖它以使其在支持类中成为public
也是惯例。
JDK1中引入了clone
设计。这些天普遍的共识是java clone
设计包含一些缺陷。有些人更喜欢创建一个克隆构造函数(例如public Color(Color toCopy) {this.color = toCopy.color;}
)