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;
 }
}

“這個方法很有意思,我肯定會用的,偶爾……”