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

Java clone() 實作完整範本:LocalCopy 本地副本模式與參考比較

     編輯:Java 相關知識

理解 clone() 細節後,可建立便利複製的類別提供本地副本:

//: LocalCopy.java
import java.util.*;
class MyObject implements Cloneable {
    int i;
    MyObject(int ii) { i = ii; }
    public Object clone() {
        Object o = null;
        try { o = super.clone(); }
        catch (CloneNotSupportedException e) { System.out.println("MyObject can't clone"); }
        return o;
    }
    public String toString() { return Integer.toString(i); }
}
public class LocalCopy {
    // 傳參考:修改外部物件
    static MyObject g(MyObject v) { v.i++; return v; }
    // 本地副本:clone 後修改不影響原物件
    static MyObject f(MyObject v) {
        v = (MyObject)v.clone(); // 關鍵:建立本地副本
        v.i++;
        return v;
    }
    public static void main(String[] args) {
        MyObject a = new MyObject(11);
        MyObject b = g(a);
        System.out.println(a == b ? "a == b" : "a != b"); // 參考相等
        System.out.println("a = " + a); // 12
        System.out.println("b = " + b); // 12
        MyObject c = new MyObject(47);
        MyObject d = f(c);
        System.out.println(c == d ? "c == d" : "c != d"); // 參考不等
        System.out.println("c = " + c); // 47
        System.out.println("d = " + d); // 48
    }
} ///:~

關鍵要點

  1. clone() 必須為 public 才能被外部呼叫
  2. 首行呼叫 super.clone()(Object 中為 protected,衍生類可存取)
  3. Object.clone() 執行前檢查 Cloneable,未實作則拋出 CloneNotSupportedException,故以 try-catch 包裹

參考傳遞 vs 本地副本

  • g():按參考傳遞,修改外部物件,回傳同一參考(a == b 為真)
  • f():v = (MyObject)v.clone() 建立本地副本,修改隔離,回傳新參考(c != d)

語句 v = (MyObject)v.clone() 看似怪異,實則合法:參考 v 指向原物件,呼叫 clone() 產生副本,回傳 Object 參考,造型後指派回 v,原參考被覆蓋指向新副本。

Java 等價比較本質

==/!= 僅比較參考位址,非物件內容。參考位址相同即視為「等價」,實質檢測「是否因別名指向同一物件」。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved