2013-08-06 69 views
-5

對於每個程序告訴請,方法的調用數量是無限或最終並解釋爲什麼。這些都是來自布洛赫的例子 - Java Puzzlers#45StackOverFlowError +遞歸有趣的把戲

1) 

    public static void main(String[] args) 
     { 
     try 
     { 
      main(args); 
     } 
     catch(StackOverflowError e) 
     { 
      main(args); 
     } 
    } 

2) 

    public static void main(String[] args) 
     { 
     try 
     { 
      main(args); 
     } 
     catch(StackOverflowError e) 
     { 
      main(args); 
     } 
       finally 
       { 
         main(args); 
       } 
    } 

有一點我想搞清楚。例如,JVM中Stack的深度是1024.我們運行這個程序,方法Main被調用1024次,然後發生StackOverflowError,我們首次進入catch塊,在那裏再次調用main方法。那麼,我們現在在哪個層面上呢? 1024? 1023? 1025?或者第一個堆棧被填充,然後另一個堆棧被創建,我們從0開始?怎麼運行的?第二個例子中,我們最後還會阻止嗎?

+2

你爲什麼不試試呢? –

+2

我確定你還沒讀過Bloch - Java Puzzlers#45 – OxomHuK

+0

請注意,如果在finally塊中拋出異常,它將被拋出finally塊並將替換之前從catch中拋出的異常。另外你的問題是「填充第一個堆棧而另一個堆棧被創建」是沒有意義的。給定的呼叫路徑只有一個調用棧。 –

回答

1

在第一個例子中,讓我們看待整個函數,就像它沒有真正調用它自己一樣。基本上,進行方法調用,如果堆棧溢出,則進行相同的方法調用。顯然,如果第一次調用導致堆棧溢出,則沒有任何更改,第二次調用會導致堆棧溢出,但未捕獲並導致異常顯示。實質上,如果它調用的方法溢出堆棧,那麼方法調用的數量是有限的。現在,因爲方法調用總是自己調用,所以方法會在某個時間點溢出堆棧,並且由於之前我們已經證明,方法調用的數量是有限的。

現在,這是數學思維方式在計算機編程中的一個很好的應用。

對於第二個例子,除了因爲finally塊,在異常報告之前容忍兩個堆棧溢出,並且相同的邏輯將導致相同的結果,它完全相同。

相關問題