Error不是例外.所以捕捉任何異常都不會捕獲StackOverflowError.
所以讓我們先來看一下“明顯的錯誤” – (這段代碼不太適合這個答案后面的說明):
catch(Throwable e){
System.out.println("Catch");
}
如果您進行此更改,您將發現代碼仍然不打印.但是它不會打印出一個非常不同的原因…
抓住任何錯誤(包括StackOverflowError)是非常不鼓勵的.但是在這里,你不僅僅是捕捉到它,而是在堆棧頂部發現它.即使你的代碼(沒有上面的改變),這個錯誤被finally塊有效地捕獲.
當堆棧已滿時,會發生StackOverflowError,并嘗試向其添加更多信息.所以當你抓到錯誤時,堆棧仍然是滿的.由于堆棧已滿,您無法調用任何方法(甚至打印到控制臺).所以在成功打印之前,第二個StackOverflowError被拋出.
其結果是:
>捕捉錯誤
> trys打印錯誤
>導致另一個錯誤,因為它無法打印
>最后調用,因為最后總是被調用.
>導致另一個錯誤,因為它不能調用main
>將錯誤級聯回到前一個調用,這個調用遇到相同的錯誤.
這里的關鍵是最終會開始打印東西.但是打印的調用使用了大量的堆棧空間,并且您的代碼將不得不通過上述點重復和錯誤很長一段時間才能釋放足夠的堆棧空間來打印.根據Holger的評論,Oracle的Java 8將println stack框架所需的主堆棧數量放在50左右.
250 = 1,125,899,906,842,624
這就是為什么你應該永遠不會遇到錯誤.
只有少數借口允許你打破這個規則,你已經發現了第一手,如果你打破它,會出什么問題.