clone 方法和 Cloneable 接口 - 1

“嗨,阿米戈!”

“嗨,金。”

“我将向您介绍 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;
 }
}

“这个方法很有意思,我肯定会用的,偶尔……”