2012-05-24 101 views
1

由於很長一段時間,我被困在此。克隆()身體深度克隆?

告訴我,下面的代碼是否構成一個克隆?

class A 
{ 
int i; 
    int j; 
    String str; 
    A() 
    { 
     i=10; 
     j=30; 
     str="Hello"; 
    } 
    A(A a) 
    { 
     this.i=a.i; 
     this.j=a.j; 
     this.str=a.str; 
    } 
} 
class B 
{ 
    public static void main(String args[]) 
    { 
     A a = new A(); 
     A a1 = new A(a); 
     /* I want to make clone like this. */ 
     } 
} 

當我運行這段代碼,當我打印a和a1的散列碼時,它們是不同的。 但是我的一些朋友說這不是製作克隆的正確方法。 你必須實現Cloneable接口,是否真的有必要? 在我看來,如果我想要在衍生參考變量的情況下進行深層複製,這可能是一個好方法。 謝謝。

+1

您的代碼不會進行深度複製,甚至不會進行淺度複製('str'不同)。你真的想要一個深刻的副本嗎?另外,你的朋友是對的。你有什麼叫做_copy constructor_。這是一種非常好的編碼風格。另外,除非實現'hashcode()',否則您應該期望不同的對象具有不同的哈希碼。 –

+0

我的代碼完美地製作了一個深層副本。所有字段的值都相同。是的,這是一個執行深層複製的複製構造函數。「顯然,我沒有重寫hashcode(),所以我不會得到相同的哈希代碼。但爲什麼它不是在你的意見深層複製? –

+0

首先,您在我發佈我的評論後更改了代碼,因此我的評論部分現在無關緊要。它確實做了一個_shallow_副本。但是,如果您想要深度複製,則需要執行'this.str = new String(a.str)'。由於String是不可變的,所以這不是什麼大問題,但它也不是一個深層次的拷貝。 –

回答

2

您需要實現Clonable接口才能克隆對象。你已經實現的是一個拷貝構造函數。複製構造函數比實現Clonable更可取。

你複製的對象與它被複制的對象有不同的hashcode/equals的原因是你沒有重寫你的A類中的hashcode或equals函數,所以它檢查的是標識而不僅僅是相等(精確的相同的對象,而不是具有相同值的對象)。通過重寫hashcode/equals,你可以讓你的類比較它的屬性值。