簡體   English   中英

java中如何區分對象和變量

[英]How to distinguish object and variable in java

我在 java docs中遇到了這個問題。 第二個問題的答案是在代碼執行后,“兩個對象都沒有資格進行垃圾收集。數組students不適合垃圾收集,因為它有一個對對象studentName的引用,即使該對象已被賦值為 null。對象studentName也不符合條件,因為 students[0] 仍然引用它。” 但我不認為studentNamestudents是對象,它們只是引用對象的變量,它們不會被垃圾回收。 我認為只有字符串“Peter Parker”是下面代碼中的對象。 怎么了?

...
        String[] students = new String[10];
        String studentName = "Peter Parker";
        students[0] = studentName;
        studentName = null;
....

這種說法在更多層面上是根本錯誤的,而不是混淆對象和變量。

你是對的,它混淆了名稱和對象,達到了有史以來的最高數量。 不僅“對對象studentName的引用”是錯誤的,因為studentName不是一個對象,“即使該對象已被賦值為null ”甚至更糟,因為對象不能被賦值為null並且應該解釋該設置對null的引用並不意味着所指對象變得不可訪問,而是實現了相反的結果。

但這還沒有結束,因為整個邏輯都是錯誤的。 讓我們刪除名稱,以避免混淆。 然后,短語讀作“數組……不符合垃圾回收條件,因為它有一個對對象的引用…… ”。 這是完全錯誤的。 如果X有對Y的引用,它不會阻止X的垃圾收集,因為只有X的引用很重要。

可能阻止對數組進行垃圾回收的,是變量students持有對它的引用,但是當然,一個沒有區分變量和對象的作者,是無法表達這種關系的。

值得注意的是,如果students是一個局部變量,它並不會在任何情況下都阻止數組的垃圾回收,正如Java在對象仍然在范圍內時可以完成對象嗎? 但是為了簡化,在教程中跳過這一點可能是可以接受的,另請參閱Lie-to-children

另一個問題是,只要 JVM 中至少有一段代碼引用它,為像"Peter Parker"這樣的字符串文字創建的對象將保留在內存中,因為所有字符串文字(以及字符串類型的編譯時常量) ) 的相同內容計算為相同的對象。

如果你想走垃圾回收的簡化推理路線, students變量包含對String[]數組實例的引用,由於該引用而阻止垃圾回收,並且該數組包含對String對象的引用,這可以防止String實例進行垃圾收集(除了可能存在的其他引用)。

大多數情況下,您不應該嘗試猜測垃圾收集器可以收集什么,因為垃圾收集器的真正目的是減輕開發人員考慮這個問題的負擔。

不幸的是,文檔沒有清楚地區分變量和對象。 此片段中有兩個對象:數組new string[10]和字符串"Peter Parker" 在第 1 行中,變量students被設置為數組對象的引用; 在第 2 行中,變量studentName設置為字符串對象的引用; 在第 3 行中,數組元素 0 設置為對字符串對象的引用; 最后在第 4 行中,變量studentName設置為null

現在數組對象不能被垃圾回收,因為變量students仍然持有一個引用,而字符串對象不能被垃圾回收,因為數組元素 0 仍然有一個引用。

如果有第 5 行的變量students也設置為null ,則這兩個對象都可能被垃圾回收,因為兩者都不再可訪問(但字符串文字永遠不會被垃圾回收 - 但這是出於另一個原因)。 在這種情況下,數組元素 0 仍然具有對字符串對象的引用並不重要,因為數組對象本身不再可訪問。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM