2013-05-01 68 views
2

我讀了很多關於Object和Cloneable Interface的clone()方法的線程,但是我找不到我的問題的合法答案。 長話短說:爲什麼不能將對象設爲可複製的?

我發現Object有一個方法clone(),它可以「神奇地」克隆你的對象。但是,如果不實現Cloneable Interface,則不能使用該方法,因爲此接口允許Object使用clone()方法。那麼他們爲什麼這樣做?爲什麼每個對象從一開始就不應該是可複製的?

+1

像'爲什麼foo以這種方式實現?',沒有明確答案這樣的開放性問題,並不適合StackOverflow。請參閱[常見問題]。 – Keppil 2013-05-01 09:21:41

+0

你做了你的[*作業*](http://stackoverflow.com/questions/4081858/about-java-cloneable)嗎? – 2013-05-01 09:23:24

回答

3

Cloneable對於一些可變數據有意義。

它不適合

  • 一成不變的數據
  • ,你可能需要一個淺或深拷貝是有意義的。
  • 對象代表資源諸如螺紋,插座,GUI組件
  • 單和枚舉類型
  • 其中數據應僅被複制,以避免產生新的對象的可變狀態。

一些編碼風格建議保持新的可變數據對象爲最小。 Cloneable不適合所有情況,如果您製作了所有Cloneable對象,則無法將其完全關閉。

注意:有許多項目避免在任何地方使用Cloneable。

+0

對我很有幫助,非常感謝 – user2338815 2013-05-01 09:54:11

+0

說一個不可變對象上的clone對象可能只返回同一個對象。如果一個對象封裝某個對象或實體的可變狀態並封裝該對象的身份,則會發生克隆的唯一基本問題(但它很大)。克隆單個對象時,克隆可能會封裝原始狀態的分離副本,或者維護用於封裝原始狀態的對象的標識,但不能同時包含兩者。 – supercat 2013-12-30 22:12:52

+0

如果有一個約定,不可變類型應該將'clone'實現爲簡單的'return this',那麼爲值集合分配不同類型的值是有意義的(值應該實現'cloneable')和collection-of-references(引用的克隆方法將不會被使用)。爲了真正做到這一點,應該有一個'cloneableObject',它有一個始終可以工作的受保護的「magic」'memberwiseClone'方法,而不是在可能或不可以工作的對象中使用'clone'方法;對公共克隆方法的支持將獨立於來自'cloneableObject'的派生。 – supercat 2013-12-30 22:18:31

-2

克隆意味着創建對象的新副本,並且不會像分配運算符那樣共享內存位置。

  MyObject obj1 = new MyObject(); 
     obj2 = obj1; 

在這裏,在這種情況下,您對OBJ1的任何更改將在obj2的,反之亦然反映,因爲obj2的持有OBJ1的存儲位置。

但是,如果你不想要,obj2中所做的更改將在obj1中看到,或者obj1中所做的任何更改都將在obj2中看到,那麼您將執行克隆。在這種情況下,兩個對象將具有不同的內存位置。

1

因爲如果每一個對象(包括用戶定義的類的對象)可通過使用clone方法只是克隆那麼它可能導致原始對象的無意突變被克隆爲clone提供了原始的淺拷貝目的。例如:

class MyClass 
{ 
    private int val; 
    public void setVal(int i) 
    { 
    this.val = i; 
    } 
    public int getVal() 
    { 
    return this.val; 
    } 
    public static void main(String st[]) throws Exception 
    { 
    ArrayList<MyClass> ar = new ArrayList<MyClass>(); 
    MyClass mc = new MyClass(); 
    mc.setVal(50); 
    ar.add(mc); 
    ArrayList<MyClass> copy =(ArrayList) ar.clone();//Since ArrayList is cloneable 
    copy.get(0).setVal(10); 
    System.out.print(ar.get(0).getVal());//it shows 10 instead of 50!! 
    } 
} 

因此我們看到,克隆可能導致不一致原始對象的內部狀態被複制。所以爲了避免這種情況,程序員在定義類時是否會流行,以確定他/她是否想要克隆該類的對象。

+0

謝謝你的生動的例子:) – user2338815 2013-05-01 09:58:10

相關問題