2013-04-16 23 views
6

我有時會認爲如果oldObject != newObject那麼對象已經發生了變化 - 這在大多數情況下似乎是一個公平的假設,但它確實是一個錯誤的假設?獲得完全相同的對象引用兩次的機率是多少

總之,下列代碼在什麼情況下會打印「相同!」?我知道這確實是遠程可能的,因爲對象引用基本上是對象的內存地址(或者可能在某個JVM中)。但它有多可能?在實際發生之前,我們是在談論數十年的運行時間嗎?

新增

我道歉 - 請假設oldO是某種形式的weak參考,不被收集停止。可能是Weak,因爲代碼(現在)建議,或者引用存儲在某個數據庫或某個文件中。

+1

如果你可以記下第一個對象的地址,然後丟棄它,那麼這個新對象可能位於同一個地址......我想這可能發生在任何時候。 – Ridcully

+0

「那麼對象發生了變化」我相信你的意思是這個「已經被銷燬,並且一個新的代替它」。 – Alan

+0

道歉 - 我的意思是(像@Ridcully所建議的那樣)'oldO'不會阻止對象被釋放。 – OldCurmudgeon

回答

4

(我回答什麼,我覺得你真的想知道,而比你有特定的片段)

它取決於實現。對象引用的契約是,只要對象還活着,其他對象就不會與它進行比較==。這意味着在對象被垃圾回收後,VM可以自由地重用相同的對象引用。

Java的實現可以選擇使用遞增的整數用於對象引用,在這種情況下,只有在引用計數器溢出回0時才能獲得相同的對象引用。其他實現可能使用內存位置,這使得它更可能爲了同樣的參考被重用。無論如何,如果重要的話,你應該定義你自己的對象標識。

+0

謝謝 - 你是否說這是JVM的依賴?如果是的話,你提到的每個機制有什麼機會?可能性有多大?小?消失的小?我強調這是針對**相同的**對象。 – OldCurmudgeon

3

它們不可能相等。您仍舊有對舊對象的引用(oldO),所以它永遠不會被丟棄。

+0

弱引用與正常引用不同 - 整個問題是它允許所引用的對象被垃圾收集。 – Adrian

+0

此答案是在作者添加到問題之前編寫的。 –

+0

公平 - 答案應該修改或刪除。直到現在, – Adrian

1

o == oldO意味着o是與oldO相同的存儲地址。所以,除非在某個時間,你正在做o = oldOoldO = o,否則這是不可能發生的。按照傳遞性,當然,執行foo = o; oldO = foo或任何等價物都會達到相同的結果。

4

永遠不會是一樣的。 oldO將始終引用初始對象,因此它永遠不會被丟棄,並且新對象不能具有相同的地址。

更新:好像回答已更新,指定oldO是一個弱引用。在這種情況下,當物體消失時,oldO的引用將變爲空。這意味着它永遠不會匹配JVM中的另一個對象。

+0

新對象不能有相同的地址?垃圾回收的目的不是爲了釋放內存,以便其他對象可以重新使用相同的內存? – Adrian

+0

@Adrian,舊的對象永遠不會被垃圾收集,因爲它總是被變量'oldO'引用。如果你重置'oldO',那麼你永遠不會知道它最初指的是什麼。順便說一句,JVM可以在運行時移動你的對象,所以你不能保證'oldO'總是相同的(即對象的物理/虛擬內存中的地址可以隨時改變)。 – akostadinov

+0

這不是事實,因爲oldO是一個WeakReference。 – Adrian

0

它永遠不會發生。

您的第一個對象(oldO)存儲在特定的內存位置。

只要oldO被引用,您的第二個對象將系統地在另一個memery位置被引用。

因此,oldO == o將比較兩個內存地址,這將永遠是不同的。

如果您解引用oldO,它將被垃圾回收,並且您將有可能在這個相同的地址創建一個新的對象。但是您將無法將其與oldO進行比較,因爲它已被取消引用。

1

首先,內存地址是不相關的。 Java不是C.對象身份是JVM的一種實現 - 它可能或可能不依賴於內存地址,但更可能不會,因爲JVM可以自由地在內存中移動對象,但必須保持其身份。

但是無論如何。因爲你持有對原始對象的引用,所以第二個不能是「相同」對象。

+0

他們對原始對象持有* weak *引用。在這種情況下,這是一個非常重要的區別,也是OP問題的重點。 – Adrian

+0

@Adrian這個問題是在*我回答後編輯的*。儘管如此,它並沒有改變我的答案,因爲如果收集到的話,弱引用實際上會爲空。 – Bohemian

+0

它當然應該改變你的答案:「因爲你持有對原始對象的引用」是錯誤的。 – Adrian

0

通過引用舊對象,可以防止它被垃圾收集,因此您可以防止這些內存可用於新對象,因此它們永遠都不會相同。

我想知道,如果你使用的SoftReference的,你可以保留舊對象的引用,同時允許它作爲垃圾回收BUT:曾經的老物件收集

1)我承擔,在SoftReference的被設置爲空,

2),這是人爲地試圖迫使情況,所以並沒有真正證明什麼:-)

0

According to the documentation,當垃圾收集對象時,弱引用將被清除。它沒有具體說明被「清除」的含義,但大概設置爲空。如果它實際上設置爲null,則不管其存儲位置如何,null都不會聲明爲任何對象引用。

相關問題