2016-03-05 94 views
8

請考慮以下Java中的簡單示例。通過調用new B(0)創建對象會發生什麼?首先,在內存中創建一個類型爲B的對象。然後,表達式1/n將拋出異常。但是,根據下面的Java規範(第12.6.1節),創建的對象將永遠不會完成。那麼我們是否會發生內存泄漏?在Java中,評估構造函數調用的參數時會發生什麼情況會引發異常?

請注意,我不是問「構造函數是否可以拋出異常」,而是「如果構造函數在特定情況下拋出異常,會發生什麼。」

對象o直到它的構造函數調用了o上的Object的構造函數並且該調用已成功完成(即,沒有引發異常)才能被終結。

class A { 
    int n; 
    A(int n) { 
     this.n = n; 
    } 
} 

class B extends A { 
    B(int n) { 
     super(1/n); 
    } 
} 
+2

我認爲「可定製的」指的是在對象被GCed時調用'finalize()',而不是*該對象是否會被GCed。 –

+3

可能的重複[可以構造函數在Java中引發異常?](http://stackoverflow.com/questions/1371369/can-constructors-throw-exceptions-in-java) – mawalker

+0

@DavidEhrmann正確。一個對象是否可以終結是很無關緊要的,因爲幾乎沒有你應該使用終結器的場景。 – biziclop

回答

4

你引述的可達性和finalizability區分的部分:

每個對象的特徵可以是兩個屬性:它可能是可達的,終結可達的,或無法訪問,它也可以未定型,可定型或最終定型。

因此,一個對象可以獨立地到達或不可到達,並且可終結或不可終結。

在你提到的Object構造從來沒有運行,因此該對象不是終結,但OTOH構造已拋出異常,因此new結果給一個變量賦值不會發生,所以它是不可達的情況下。

所以沒有內存泄漏。

+1

您可以使用'-verbose:gc'運行[這個小測試](http://pastebin.com/A5tMhAxw)來驗證這一點。事實上,「失敗」的情況下運行速度更快,清除內存的速度要快得多,這聽起來只有在看到如何實現最終化,以及它如何阻止GC並減慢所有內容 – biziclop

相關問題