小编典典

Try-finally 阻止 Error

all

看看以下两种方法:

public static void foo() {
    try {
        foo();
    } finally {
        foo();
    }
}

public static void bar() {
    bar();
}

清楚地运行会bar()导致 a StackOverflowError,但运行foo()不会(程序似乎无限期地运行)。 这是为什么?


阅读 68

收藏
2022-04-07

共1个答案

小编典典

它不会永远运行。每次堆栈溢出都会导致代码移动到 finally 块。问题是这将需要非常非常长的时间。时间顺序是 O(2^N),其中 N 是最大堆栈深度。

想象一下最大深度是5

foo() calls
    foo() calls
       foo() calls
           foo() calls
              foo() which fails to call foo()
           finally calls
              foo() which fails to call foo()
       finally
           foo() calls
              foo() which fails to call foo()
           finally calls
              foo() which fails to call foo()
    finally calls
       foo() calls
           foo() calls
              foo() which fails to call foo()
           finally calls
              foo() which fails to call foo()
       finally
           foo() calls
              foo() which fails to call foo()
           finally calls
              foo() which fails to call foo()
finally calls
    foo() calls
       foo() calls
           foo() calls
              foo() which fails to call foo()
           finally calls
              foo() which fails to call foo()
       finally
           foo() calls
              foo() which fails to call foo()
           finally calls
              foo() which fails to call foo()
    finally calls
       foo() calls
           foo() calls
              foo() which fails to call foo()
           finally calls
              foo() which fails to call foo()
       finally
           foo() calls
              foo() which fails to call foo()
           finally calls
              foo() which fails to call foo()

将每个级别工作到 finally 块中需要两倍的时间,堆栈深度可能是 10,000 或更多。如果您每秒可以进行 10,000,000 次调用,这将花费
10^3003 秒或比宇宙年龄更长的时间。

2022-04-07