程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> java的“別名”以及clone機制

java的“別名”以及clone機制

編輯:關於JAVA

什麼是別名?用個簡單的例子說明

public class Aliases{ int i; public Aliases() { i=1; }

public Aliases(int i) { this.i=i; }

public static void main(String args[])

{ Aliases A=new Aliases(); Aliases B=A; //A和B指向了同一個對象,A和B互為別名

System.out.println("A.i and B.i:"+A.i+" "+B.i); System.out.println("增加B:");

B.i++;

System.out.println(("A.i and B.i:"+A.i+" "+B.i); } }

輸出:

A.i and B.i:1 1

增加B: A.i and B.i:2 2 很明顯,A和B指向了同一個對象,B=A這個操作只是把A的引用復制給了B,而對象並未拷貝。Java是通過Rerference來操作對象的,上面是一個顯式別名的例子,當你往函數內傳遞對象時也會發生別名,如下:

public class Aliases{ int i; public Aliases() { i=1; }

public Aliases(int i) { this.i=i;

}

public Increment(Aliases AS) { AS.i++;

} public static void main(String args[])

{ Aliases A=new Aliases();

System.out.println("A.i before Increment:"+A.i);

Increment(A); System.out.println("A.i after Increment:"+A.i); } }

你可以看到A在經過函數Increment()的調用後i的值發生了變化。

在某種情況下,你可能不希望傳入的對象發生變化,希望函數內的對象只是傳入對象的副本,對這個副本的改變不至於影響原來的對象,那該如何處理?我們知道C++是通過把參數聲明了const,就意味著此參數不可改變,但是別忘了,C++有所謂的拷貝構造函數,所以在函數中的對象確實是拷貝,而java並未支持拷貝構造函數,原因很明顯,java傳遞對象的引用,你就算拷貝也只是引用的拷貝而已(所以有人說Java本質上只有傳值)。

那麼就沒辦法了嗎?有的,那就是“克隆機制”,在根類Object已經定義了clone()方法,你所要做的只是實現cloneable接口,並覆寫clone()方法,典型的應用如下

class CloneClass implements Cloneable{ public int aInt; public Object clone(){ CloneClass o = null; try{ o = (CloneClass)super.clone(); }catch(CloneNotSupportedException e){ e.printStackTrace(); } return o; } }

調用super.clone()方法,它會為你自動處理存儲分配和復制操作,從而實現了對象的深層拷貝。

我們又知道,同過serilization也可以實現對象的深層拷貝啊,為什麼不用這個?根本原因在於效率上的巨大差異,clone()雖然一開始好象很復雜,但畢竟沒有對象的讀寫那麼耗費資源。

有了clone機制,你就可以在方法調用內部制造一個對象的副本了,它是局域性,對它的任何操作都不至於影響原對象的狀態了。我個人認為,這點對於編寫一個安全的大型程序是非常重要的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved