2013-02-08 74 views
1

我正在從java認證書中做一些練習。在一個關於垃圾回收的問題,他們提出了下面的代碼:Java之後的垃圾收集器null

class Test { 
    private Demo d; 
    void start() { 
     d = new Demo(); 
     this.takeDemo(d); 
    } 
    void takeDemo(Demo demo) { 
     demo = null; 
     demo = new Demo(); 
    } 
} 

,問題是

當演示對象,在第4行創建的,符合垃圾收集 ?

我會說它可以在指令demo = null之後收集;因爲有它不再引用,但在他們給出的答案是:

當運行該代碼的實例是由符合垃圾收集

我缺少什麼?

回答

5

Java is "pass-by-value",因此該聲明demo = null;僅影響demo的本地副本takeDemo。它不會將d設置爲null,因此只要封閉實例可到達,就可以訪問它。

+0

我更傾向於說Java是pass-by-pointer。 – Dukeling 2013-02-08 12:27:25

+4

@Dukeling事實並非如此。 – assylias 2013-02-08 12:27:42

+0

如果比較Java和C++,Java更適合傳遞指針(基本上完全)。你可以說它是一個指針的傳值,但是你只是把事情複雜化得超過必要(然後你可以在C++中說相同的東西)。請注意,我不會與其餘的答案爭論。 – Dukeling 2013-02-08 12:31:16

0

在方法start()完成之前,對局部變量d的引用是「有效」的。在此之前,垃圾收集不應該釋放它。

1

您正確地注意到demo設置爲null。但d不是。它仍然持有對同一個對象的引用。因此,答案。

1

因爲demo = null只是改變方法參數demo的值,該方法是本地的,並且不影響字段d的值。請記住,在Java中,所有方法參數都是按值傳遞的。

0

第4行的演示只能與Test實例一起收集。或者如果您再次調用啓動方法(舊的Demo將被收集並且新創建)

takeDemo方法對第一個Demo沒有任何影響。但它創建了第二個Demo。第二個Demo可以在takeDemo方法完成後立即收集。

0

當你調用this.takeDemo(d);參考d的值被複制到參數demo中,因此d和demo都引用了第4行中創建的對象。現在,當您將變量demo設置爲null時,方法內部仍然保存引用,因此對象將會一旦Instance of Test類被垃圾收集,就有資格進行垃圾收集。