3

我试图弄清楚 in 的执行try-catch-finally顺序java。我认为执行顺序应该是

  1. 尝试
  2. 捕获(如果发生错误/捕获异常)
  3. finally (是否捕获到异常)

但我对以下结果感到困惑

public class TryCatchFinally {
static int i = 0;
public static void main(String[] args) {
    try {
        System.out.println(i++);
        main(args);
    } catch (StackOverflowError e) {
        System.out.println("Catch");
    } finally {
        System.out.println("Finally");
    }
 }
}

输出(输出的一部分)

9127
9128
9129
9130
CatcFCatch // what is the wrong here???
Finally
Finally // there are more Finally printed here.

我的问题是这里到底发生了什么?

让我添加更多为什么它不打印"Catch"???

我在运行时将其输出IntelliJ IDEA。但是当我跑进去时,我会terminal按如下方式退出。

9151
9152
9153
9154CatchFinallyCatch
Finally
Finally
Finally
Finally
4

3 回答 3

7

很有可能您在调用内部的某个地方遇到了 stackoverflow 错误println(可能是因为正在进行一些刷新或类似的事情),从而使该println方法处于不一致的状态(打印了它应该打印的部分内容)。

当您已经在处理 a时,很容易发生这种情况StackOverflowError,因为此时您已经危险地接近溢出堆栈(因为您刚刚从一个非常接近问题的点从一个堆栈中恢复)。

我的解释是这样的:

  • main 递归调用自己很多...
  • 您第 9130 次递归调用 main
  • 它打印那个数字
  • 它第 9131 次自称
  • 它尝试打印该数字,但抛出 a StackOverflowError,因为堆栈已满
  • 您输入 catch 并尝试打印“Catch”
  • 在那次println通话中,另一个StackOverflowError发生了
  • finally 块被执行,因为catch块完成(突然)
  • 它试图打印“终于”
  • 那次 println通话中, StackOverflowError发生了另一件事
  • 在第 9130 次调用StackOverflowError中捕获main
  • 它打印“Catch”(成功,因为堆栈现在短了 1 个元素!)
  • finally 块被执行并Finally成功打印,因为堆栈现在短了 1 个元素。
  • 更多 finally 块执行。
于 2013-11-06T10:08:05.800 回答
1

这是因为对 main 的递归调用。因此,当您在 main 中调用 main 时,您将多次输入 try catch 块,并且您从它返回的次数与您在第一次 StackOverflow 发生后输入它的次数相同。这就是多次决赛的原因。

编辑:当我看到一些downvotes,没有任何合理的解释,如果有人认为我错了,只需i在 finally 块中打印带有递减的该死的计数器。

public static void main(String[] args) {
    try {
        System.out.println(i++);
        main(args);
    } catch (StackOverflowError e) {
        System.out.println("Catch");
    } finally {
        System.out.println("Finally: "+ (i--));
    }
 }
于 2013-11-06T10:08:45.933 回答
0

您是否使用 IDE(eclipse 或类似的),如果是,那么可能是由于这个原因。

这是我尝试的结果-

// 代码

public static void main(String[] args) throws IOException {

    File file = new File("resources/ouput.txt");
    file.createNewFile();
    PrintStream printStream = new PrintStream(file);
    System.setOut(printStream);

    overflowTester(0);

}

private static void overflowTester(int index) {
    try {
        System.out.println(index++);
        overflowTester(index);
    } catch (StackOverflowError  e) {
        System.out.println("Catch");
    } finally {
        System.out.println("Finally");
    }
}

// 输出

0
1
2
3
4
5
6
7
8
9
10
...
...
...
9666
Catch
Finally
...
...
Finally

注意:'9666' 打印在第 9667 行,最后一个 finally 在第 19336 行。

就我而言,运行以下程序:

private static int index = 0;

public static void main(String[] args) throws IOException {

    try {
        System.out.println(index++);
        main(args);
    } catch (StackOverflowError  e) {
        System.out.println("Catch");
    } finally {
        System.out.println("Finally");
    }

}

从命令提示符中,产生了类似的结果:

0
1
2
3
4
5
...
...
9667
Catch
Finally
...
...
Finally

'9667' 打印在第 9668 行,最后一个 'Finally' 打印在第 19338 行。

于 2013-11-06T10:55:42.783 回答