2014-03-24 52 views
13

這段代碼爲什麼會完全破壞輸出?奇怪的Java StackOverflowError?

public class Main { 
    public static void main(String[] args) { 
     System.out.println(); 

     rec(); 
    } 

    private static int rec() { 
     try { 
      return rec(); 
     } catch(StackOverflowError e) { 
      System.out.println("Boo."); 
      return 0; 
     } 
    } 
} 

示例輸出我得到:Boo.Boo.Boo.Boo.Boo.Boo.Boo.Boo.Boo.

+1

當我運行代碼時,我只得到一個Boo。 – libik

+1

也許試着解釋你認爲這是怎麼工作的。 – csmckelvey

+1

你問你爲什麼得到多個boo的輸出,而不是一個?你的噓聲在一條線上? – NESPowerGlove

回答

9

的問題是類似於這個問題的問題:Stack overflow error handling in finally block

基本上,println調用處理爲StackOverflowException被觸發進一步StackOverflowException。正在對rec()進行封閉呼叫處理。這繼續(打開rec()調用,因爲我們去),直到異常處理程序有足夠的空間完成 println調用。中間調用可能將字符添加到輸出緩衝區,然後提升SOE。

一個精確的解釋需要對PrintStream和流棧的代碼進行取證分析......一直到它調用本地代碼的地步。


如果你想有一個薈萃的解釋,它是你的代碼試圖從Error ......它的javadoc說的東西,你不應該試圖做恢復。作爲一般規則,在一個Error之後,JVM將是一個不確定的,可能是壞的狀態。在這種情況下,不確定性表現爲可能寫入或可能未寫入緩衝區的數據。這種行爲(可能)是確定性的,但是如果沒有適當的分析,就很難分析和預測。

+0

是的。 NESPowerGlove的評論非常明確,如果不是更多的話。如何從'main'方法中註釋掉'println'確實有所作爲? – dragostis

+1

我記得還有一個問題,因爲深入分析的原因,但我找不到:( –

+0

你需要做我上面提到的法醫分析... –