2013-11-22 40 views
0

我一直在讀有效的Java,而且出來我過時的對象引用的項目是他的執行pop()一兩件事:有效的Java項目6 - 彈出堆棧實現

public Object pop(){ 
    if (size == 0) 
    throw new EmptyStackException(); 

    Object result = elements[--size]; 
    elements[size] = null; 
    return result; 
} 

爲什麼有必要創建一個新的參考elements?爲什麼不這樣做

elements[size] = null; 
return elements[--size] 

這會將過時的對象引用歸零,而不必創建新的對數組的重新訪問。

回答

1

這是因爲elements[size] = nullsize字段的預遞減之前沒有意義,並且會導致訪問超出邊界。

3

請注意,你的變化反轉行爲,假設size = 5,讓我們看看會發生什麼:

原件(--至上):

Object result = elements[4]; 
elements[4] = null; 
return result; 

現在你的變化(--排第二):

elements[5] = null; 
return elements[4] 

所以你的實現將返回一個不正確的值。實現需要拉出頭部,然後將其設置爲空作爲一個單獨的步驟,否則將被刪除的值將丟失。看着這個實現,理論上你可以不設置這個值爲null,這樣可以節省幾行代碼,但是可能會引入內存泄漏的相當嚴重的風險(在其他地方有de - 參考他們)。此外,單獨的行使這種行爲更加明確,這對於稍後人們重新訪問代碼很有用。冗長有時是你的朋友。

0

在您的建議實現中,您已經切換了訂單,因此設置爲空的大小與上面的索引不同。如果你先做elements[--size] = null;,那麼你會失去你想要返回的參考。因爲這個原因,你需要另外一個句柄(在你清除引用的內部記錄之前引用數據),你想刪除內部引用,以便在不再需要的時候可以對垃圾進行收集。 ,雖然無法訪問,但會導致GC無法釋放該對象。