2
class exception1 {
    public static void main(String s[]) {
        String v[] = new String[2];
        try {
            main(v);
            System.out.println(5 / 0);

        }
        catch (Exception e) // or (ArithmeticException e)
        {
            System.out.println(e); // Java.lang.ArithmeticException: / by zero

        }
        finally {
            System.out.println("AAAA");
        }
        System.out.println("after finally normal execution");
    }
}

当我运行这段代码时,我会得到无数的 AAAA,直到发生 stackoverflow 错误。我的问题是 main(v); 再次调用main,但最终运行:(?控制流有点出乎我的良心。终于如此嚣张以至于它甚至不关心main?

4

4 回答 4

4

首先,注意那StackOverflowError是 anError而不是 an Exception,所以它不会被你的catch (Exception e).

抛出时StackOverflowError,该异常将在调用堆栈中向上传播。每次堆栈帧异常返回时,都会执行它的 finally 子句。

0/5您可能已经发现,该表达式不可访问。)

这是发生了什么的图片:

                                                               Output
main()
   main()
       main()
          ...
             main()

                 throw Stack-overflow!
                 Print AAAA before returning exceptionally     AAAA

             rethrow Stack-overflow!
             Print AAAA before returning exceptionally         AAAA

         ...                                                   ...

      rethrow Stack-overflow!
      Print AAAA before returning exceptionally                AAAA

   rethrow Stack-overflow!
   Print AAAA before returning exceptionally                   AAAA

Uncaught stack-overflow error, print stacktrace.               Exception dump.
于 2012-07-20T07:09:55.110 回答
2

另一个带有程序解释的答案..

class TryFinallyDemo
{
    static int counter;

    public static void main(String s[])
    {
        int localCounter=0;
        String v[] = new String[2]; 

        try{ 
            counter++;
            localCounter = counter;
            main(v); 
            System.out.println(5/0);                                     
        } 


        catch(Exception e)  // or (ArithmeticException e) 
        {   
            System.out.println(e); // Java.lang.ArithmeticException: / by zero 
        }                                      

        finally{ System.out.println("AAAA.. Local Counter is " + localCounter);  }      

        System.out.println("after finally normal execution");  

    } 
}

这个例子清楚地展示了一旦​​抛出 StackOverflow 错误,堆栈是如何从下到上回调的。

输出片段:

AAAA.. Local Counter is 47
AAAA.. Local Counter is 46
AAAA.. Local Counter is 45
AAAA.. Local Counter is 44
AAAA.. Local Counter is 43
AAAA.. Local Counter is 42
AAAA.. Local Counter is 41
AAAA.. Local Counter is 40
AAAA.. Local Counter is 39
AAAA.. Local Counter is 38
AAAA.. Local Counter is 37
AAAA.. Local Counter is 36
AAAA.. Local Counter is 35
AAAA.. Local Counter is 34
AAAA.. Local Counter is 33
AAAA.. Local Counter is 32
AAAA.. Local Counter is 31
AAAA.. Local Counter is 30
AAAA.. Local Counter is 29
AAAA.. Local Counter is 28
AAAA.. Local Counter is 27
AAAA.. Local Counter is 26
AAAA.. Local Counter is 25
AAAA.. Local Counter is 24
AAAA.. Local Counter is 23
AAAA.. Local Counter is 22
AAAA.. Local Counter is 21
AAAA.. Local Counter is 20
AAAA.. Local Counter is 19
AAAA.. Local Counter is 18
AAAA.. Local Counter is 17
AAAA.. Local Counter is 16
AAAA.. Local Counter is 15
AAAA.. Local Counter is 14
AAAA.. Local Counter is 13
AAAA.. Local Counter is 12
AAAA.. Local Counter is 11
AAAA.. Local Counter is 10
AAAA.. Local Counter is 9
AAAA.. Local Counter is 8
AAAA.. Local Counter is 7
AAAA.. Local Counter is 6
AAAA.. Local Counter is 5
AAAA.. Local Counter is 4
AAAA.. Local Counter is 3
AAAA.. Local Counter is 2
AAAA.. Local Counter is 1
Exception in thread "main" java.lang.StackOverflowError
    at java.lang.String.indexOf(String.java:1395)   
于 2012-07-20T07:24:31.130 回答
2

我调试了程序,这是流程:

main()-> main()-> main-> ........得到了 stackoverflow 异常 -> finally -> finally -> finally ->..... 控制 stackoverflow 异常从 main 转移到主线程() 方法和主线程处理stackoverflow异常

输出

AAAA
AAAA
AAAA
AAAA
....
AAAA
AAAA
AAAA
Exception in thread "main" java.lang.StackOverflowError
    at java.util.concurrent.locks.AbstractOwnableSynchronizer.<init>(Unknown Source)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.<init>(Unknown Source)
    at java.util.concurrent.locks.ReentrantLock$Sync.<init>(Unknown Source)
    at java.util.concurrent.locks.ReentrantLock$NonfairSync.<init>(Unknown Source)
    at java.util.concurrent.locks.ReentrantLock.<init>(Unknown Source)
    at java.util.concurrent.ConcurrentHashMap$Segment.<init>(Unknown Source)
    at java.util.concurrent.ConcurrentHashMap.ensureSegment(Unknown Source)
    at java.util.concurrent.ConcurrentHashMap.putIfAbsent(Unknown Source)
    at java.lang.ClassLoader.getClassLoadingLock(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at test.exception1.main(Exception1.java:17)
    at test.exception1.main(Exception1.java:7)
    at test.exception1.main(Exception1.java:7)
    ....
    at test.exception1.main(Exception1.java:7)
    at test.exception1.main(Exception1.java:7)
    at test.exception1.main(Exception1.java:7)
于 2012-07-20T07:29:05.740 回答
1

main(v)在到达5/0操作之前调用,因此不会引发异常 - 发生无限循环。

于 2012-07-20T07:10:10.430 回答