2011-07-19 43 views
4
public class Foo { 

    public static void main(String[] args) { 
     foo(); 
    } 

    public static void foo() { 
     try { 
      System.out.println("try"); 
      foo(); 
     } catch (Throwable e) { 
      System.out.println("catch"); 
      foo(); 
     } finally { 
       System.out.println("finally"); 
       foo(); 
     } 
    } 
} 

谁能解释这段代码的输出?java try-catch-finally递归问题

1.输出基于Eclipse(无尽的)客户端模式:

 

    try 
    try 
    .... 


    ... 
    ... 
    tryfinallyfinally 
    tryfinallyfinally 
    try 
    try 
    try 
    tryfinallyfinally 
    tryfinallyfinally 
    try 
    tryfinallyfinally 
    tryfinallyfinally 
    try 
    .... 
    .... 

在Linux 2.输出(崩溃)服务器模式:

 

    try 
    try 
    ... 

    ... 
    try 
    try 
    try 
    try 
    try 
    try 
    MISSING EXCEPTION HANDLER for pc 0x00002aaaab1c53f0 and handler bci -1 
     Exception: 

    Compiled exception table : 
    ExceptionHandlerTable (size = 3304 bytes) 
    catch_pco = 700 (1 entries) 
     bci -1 at scope depth 0 -> pco 11039 
    catch_pco = 1736 (1 entries) 
     bci -1 at scope depth 0 -> pco 11473 
    catch_pco = 1756 (1 entries) 
     bci -1 at scope depth 0 -> pco 11433 
    catch_pco = 1776 (1 entries) 

+6

***谁能解释这段代码的输出?***:可能是**你**。你运行这个时得到了什么? –

+6

...计算器 – MarcoS

+2

输出确实是意外: 尝试 尝试 尝试 tryfinallyfinally tryfinallyfinally 尝试 tryfinallyfinally tryfinallyfinally 尝试 尝试 tryfinallyfinally tryfinallyfinally 尝试 tryfinallyfinally tryfinallyfinally 尝试 尝试 尝试 试 –

回答

8

我想我还记得这从书中的“Java谜题”。 try块会执行一个无界的递归,这会很快导致StackOverflowError被抛出。尝试和捕获块恢复递归,但与相应较小的剩余堆栈。然而,随着每个递归调用返回,剩余堆栈会再次变大...

最终结果是一个调用图,它根据堆栈的大小形成深度树;与主流JVM的默认堆栈大小相比,树会变得非常大,以至于您必须等待很多次,才能完全遍历数十亿年,并终止程序。

编辑:这就是你在客户端模式下看到的:遍历调用图。在服务器模式下,您在Linux上看到的是JVM错误或硬件缺陷(错误的RAM可能具有此效果)。

+0

我的猜测是这是在Linux上的JIT中的错误。 –

+0

许多,许多,更多的零:) - http://stackoverflow.com/a/32319720/2158288 – ZhongYu