首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java clone() 控制機制完整指南:六種策略與實作範例

     編輯:Java 相關知識

單純將 clone() 設為 private 無法禁用複製(衍生類無法縮小存取範圍)。針對類別的複製能力,有六種控制策略:

  1. 保持中立:不處理複製。衍生類自行決定。僅當 Object.clone() 對欄位操作合理時適用。
  2. 標準支援:實作 Cloneable、覆寫 clone() 呼叫 super.clone()、捕獲所有例外(不拋出)。
  3. 條件式支援:類別持有其他物件參考(如集合類),嘗試複製所有元素;若拋出例外則讓其傳播。
  4. 不實作 Cloneable 但提供 protected clone():正確複製欄位行為,衍生類可覆寫並呼叫 super.clone()。衍生類若要正常運作需自行實作 Cloneable。
  5. 拋出例外防止複製:不實作 Cloneable,覆寫 clone() 拋出 CloneNotSupportedException。衍生類若呼叫 super.clone() 會被阻擋。
  6. final 類別徹底禁用:將類別設為 final,覆寫 clone() 拋出例外。唯一能確保複製被禁止的方法(final 防止繼承繞過)。涉及安全物件或控制實例數量時,另將建構子設為 private 提供特殊工廠方法(如 Singleton 模式)。

完整實作範例:CheckCloneable.java

//: CheckCloneable.java
class Ordinary {} // 中立
class WrongClone extends Ordinary { // 錯誤示範:覆寫但未實作 Cloneable
    public Object clone() throws CloneNotSupportedException {
        return super.clone(); // 拋出例外
    }
}
class IsCloneable extends Ordinary implements Cloneable { // 標準正確
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class NoMore extends IsCloneable { // 拋出例外關閉複製
    public Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }
}
class TryMore extends NoMore { // 正確呼叫 super.clone() 繼承禁用
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class BackOn extends NoMore { // 繞過禁用:不呼叫 super.clone()
    private BackOn duplicate(BackOn b) { return new BackOn(); }
    public Object clone() { return duplicate(this); }
}
final class ReallyNoMore extends NoMore {} // final 徹底禁用
public class CheckCloneable {
    static Ordinary tryToClone(Ordinary ord) {
        String id = ord.getClass().getName();
        Ordinary x = null;
        if(ord instanceof Cloneable) {
            try {
                System.out.println("Attempting " + id);
                x = (Ordinary)((IsCloneable)ord).clone();
                System.out.println("Cloned " + id);
            } catch(CloneNotSupportedException e) {
                System.out.println("Could not clone " + id);
            }
        }
        return x;
    }
    public static void main(String[] args) {
        Ordinary[] ord = { new IsCloneable(), new WrongClone(),
            new NoMore(), new TryMore(), new BackOn(), new ReallyNoMore() };
        for(int i = 0; i < ord.length; i++) tryToClone(ord[i]);
    }
} ///:~

執行結果

Attempting IsCloneable
Cloned IsCloneable
Attempting NoMore
Could not clone NoMore
Attempting TryMore
Could not clone TryMore
Attempting BackOn
Cloned BackOn
Attempting ReallyNoMore
Could not clone ReallyNoMore

總結:可複製類別的四步驟

  1. 實作 Cloneable 介面
  2. 覆寫 clone()
  3. 在 clone() 中呼叫 super.clone()
  4. 在 clone() 內捕獲例外
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved