2011-11-17 49 views
0

可以說我有下面的代碼:Java奇怪的引用行爲?

public class Collection implements CollectionInterface{ 

ElementInterface[] elementArray = new ElementInterface[100]; 
int amountOfElements = 0; 

public Collection() 
{ 

} 

public Collection(CollectionInterface collection) 
{ 
    CollectionInterface tempCollection = new Collection(); 
    while(!collection.isEmpty()) 
    { 
    ElementInterface element = collection.Remove().clone(); 
    tempCollection.Add(element.clone2()); 
    elementArray[amountOfElements++] = element; 
    } 
    collection = tempCollection; 

} 

public void Add(ElementInterface element){ 
    elementArray[amountOfElements++] = element; 
} 

public ElementInterface Remove(){ 
    ElementInterface element = elementArray[amountOfElements].clone2(); 
    elementArray[amountOfElements] = null; 
    amountOfElements--; 
    return element; 
} 

public boolean isEmpty(){ 
    return amountOfElements == 0; 
} 

public CollectionInterface clone() 
{ 
    return new Collection(this); 
} 
} 

還好吧,這似乎有點奇怪,它是。但如果我使用以下代碼:

CollectionInterface collection = new Collection(); 
collection.Add(new Element("Foo")); 
collection.Add(new Element("Bar")); 
CollectionInterface collection2 = collection.clone(); 

第一個不包含任何元素了。這怎麼可能?

+0

如果你真的認爲是Java,就不要說JavaScript(它們沒有任何共同之處)。 – helpermethod

+3

...請給*真正的*代碼,而不是代碼,這相當明顯不會編譯。 –

+0

我說JavaScript嗎?我不是故意的?也許autocompletion做到了?我不確定,對不起。還有Upvoted Jon Skeet,你是​​絕對正確的。我正在編輯它,但你太快了! –

回答

1

您不能在第二個構造函數中嘗試更改輸入參數的引用。

collection = tempCollection. 

一個),這是一個語法錯誤, B)collection是一個局部變量;分配給它將不會改變構造函數的外部。

+0

這不是給我一個語法錯誤。所以你不能改變構造函數的參數引用? –

+0

其實這是我的問題。當然這不行! –

+0

然後接受我的回答將是適當的行爲,我猜。 :) – Bombe

2

它非常有意義。在構造函數中,這是由clone()與原來的集合稱爲作爲參數,可以使用:

ElementInterface element = collection.Remove().clone(); 

所以你去除原始集合元素創建新的。你不想這樣做...

這不是真的清楚如何才能達到你想要的東西,因爲它看起來像你的CollectionInterface只有AddRemove方法(這應該是addremove到遵循Java命名約定)來處理元素 - 無法以非破壞性的方式訪問集合。這是非常奇怪的集合類型。你有沒有任何理由,而不是使用內置集合呢?

編輯:啊 - 我剛剛有一個想法。 範圍內,您可以訪問您正在構建的集合的內部...因此,您可以通過調用Remove(如您現在)來破壞性地複製要從收集的集合中的元素,你已經建立了你的陣列,你可以使用:

for (int i = 0; i < amountOfElements; i++) 
{ 
    collection.Add(elementArray[i].clone2()); 
} 

......這將把元素放回去。這是可怕的儘管...

+0

這實際上並非整個交易。他試圖使用構造函數參數作爲返回值。 – Bombe

+0

@Bombe:你不明白你的意思。我看不到你在描述什麼...... –

+0

他將給定集合中的元素移動到臨時集合中,同時克隆它們(在進程中克隆它們兩次),並在構造函數結束時嘗試將臨時集合分配回原始集合。 – Bombe

1

你可以只實現Clone方法如下:

public Object Clone() { 
    Collection rv = new Collection(); 

    for (ElementInterface element : elementArray) { 
     rv.Add(element.clone()); 
    } 

    return rv; 
} 

如有必要,你可以很容易地實現這個構造函數。