
“嗨,阿米戈!”
“嗨,金。”
“我将向您介绍 clone() 方法。”
“这个方法的要点是克隆一个对象,或者换句话说,创建对象的克隆/副本/复制品。”
“调用此方法时,Java 虚拟机创建并返回调用它的对象的副本。
Object 类对克隆方法的实现非常原始:只创建一个新对象,并将原始对象的字段值赋给它的字段。
如果复制的对象包含对其他对象的引用,则将复制这些引用。不会创建这些对象的副本。”
“嗯。没什么好说的了。”
“问题是,Java 虚拟机不知道哪些对象可以或不能被克隆。例如,文件不能被克隆。System.in 流也是如此。”
“因此,完全克隆的问题被抛给了类的开发人员。”这与 equals 方法的处理方式非常相似。甚至还有可以与 hashCode 相媲美的东西:Cloneable 接口。”
“ Cloneable接口就是所谓的‘标记接口’:它没有任何方法,用于标记某些类。
“如果一个类的开发者相信这个类的对象可以被克隆,他就用这个接口来标记它(即让这个类实现 Cloneable)。”
“如果开发人员不喜欢克隆方法的标准实现,他必须编写自己的方法以正确的方式创建一个复制对象。”
“当你调用clone () 方法时,Java 会检查对象是否支持 Cloneable 接口。如果支持,则使用clone () 方法克隆对象;如果不支持,则抛出 CloneNotSupportedException。”
“换句话说,我们要么重写克隆方法,要么让类实现 Cloneable?”
“是的,但你仍然必须覆盖该方法。clone() 方法被声明为受保护的,因此它只能被其包 (java.lang.*) 中的类或其子类调用。”
“我有点困惑——那么我需要做什么来克隆一个对象?”
“如果你想使用 Object 类的 «default» 克隆方法,你需要:
“ a)将 Cloneable 接口添加到你的类中”
“ b)覆盖克隆方法并在您的实现中调用超类的实现:”
class Point implements Cloneable
{
int x;
int y;
public Object clone()
{
return super.clone();
}
}
“或者您可以完全自己编写克隆方法的实现:”
class Point
{
int x;
int y;
public Object clone()
{
Point point = new Point();
point.x = this.x;
point.y = this.y;
return point;
}
}
“这个方法很有意思,我肯定会用的,偶尔……”
GO TO FULL VERSION