在try-catch中混淆无限递归的输出 [英] Confusing output from infinite recursion within try-catch

查看:106
本文介绍了在try-catch中混淆无限递归的输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码。

public class Action {
private static int i=1;
public static void main(String[] args) {
    try{
        System.out.println(i);
        i++;
        main(args);
    }catch (StackOverflowError e){
        System.out.println(i);
        i++;
        main(args);
    }
 }

}

我是让我的价值达到 4338 正确。捕获 StackOverflowError 后输出如下所示。

I am getting i value up to 4338 correctly. After catching the StackOverflowError output getting wired as follows.

4336
4337
4338 // up to this point out put can understand 
433943394339 // 4339 repeating thrice  
434043404340
4341
434243424342
434343434343
4344
4345
434643464346
434743474347
4348
434943494349
435043504350

在此处考虑实况演示。它正常工作到 i = 4330 。实际上这是怎么发生的?

Consider Live demo here. It is working correctly up to i=4330. Actually how this happen?

仅供参考:

FYI:

我做了以下代码知道这里发生了什么。

I did following code to realize what is happening here.

public class Action {

    private static int i = 1;
    private static BufferedWriter bw;

    static {
        try {
            bw = new BufferedWriter(new FileWriter("D:\\sample.txt"));
        } catch (IOException e) {
           e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException {
        bw.append(String.valueOf(i)+" ");
        try {
            i++;
            main(args);
        } catch (StackOverflowError e) {
            bw.append(String.valueOf(i)+" ");
            i++;
            main(args);
        }
    }

}

现在上一个问题不在那里。现在值 i 最多 16824744 更正并且进一步运行。我正在跳,这可能会达到 i = 2,147,483,647 (int的最大值)的值而没有问题。

Now previous issue not there. now value of i up to 16824744 correct and and runs further. I am hopping this may runs up to value of i=2,147,483,647(max value of int) without an issue.

println()存在一些问题。下面也有类似的答案。但为什么?

There is some issue with println(). There are similar answers bellow too. But why?

实际原因是什么?

推荐答案

请注意缺席 433943394339 中的换行符。它表示在 System.out.println()中发生了错误。

Note the absence of newline characters in 433943394339. It indicates that something wrong happens inside System.out.println().

这里的要点是 System.out.println()需要一些堆栈空间才能工作,因此从 StackOverflowError > System.out.println()。

The essential point here is that System.out.println() requires some stack space to work, so that StackOverflowError is thrown from System.out.println().

以下是带有标记点的代码:

Here is your code with marked points:

public static void main(String[] args) {
    try{
        System.out.println(i); // (1)
        i++;
        main(args); // (2)
    }catch (StackOverflowError e){
        System.out.println(i); // (3)
        i++;
        main(args); // (4)
    }
}

让我们想象一下在等级上会发生什么当i = 4338 时递归N:

Let's imagine what happens at level N of recursion when i = 4338:


  • N级语句(1)打印 4338 输出 4338 \ n

  • i 增加到 4339

  • 控制流程在(2)处进入N + 1级别

  • N + 1级语句(1)尝试打印 4339 ,但 System.out.println()会抛出 StackOverflowError 在打印换行符之前。 输出 4339

  • StackOverflowError 被捕获级别N + 1,语句(3)尝试打印 4339 并再次出于同样的原因失败。 输出 4339

  • 在N级捕获异常。此时有更多可用的堆栈空间,因此声明(3)尝试打印 4339 并成功(正确打印换行符)。 输出 4339 \ n

  • i 增加并且控制流量再次进入水平N + 1(4)

  • Statement (1) at level N prints 4338. Output 4338\n
  • i is incremented to 4339
  • Control flow enters level N + 1 at (2)
  • Statement (1) at level N + 1 tries to print 4339, but System.out.println() throws a StackOverflowError before it prints a newline. Output 4339
  • StackOverflowError is caught at level N + 1, statement (3) tries to print 4339 and fails for the same reason again. Output 4339
  • Exception is caught at level N. At this point there is more stack space available, therefore statement (3) tries to print 4339 and succeeds (newline is printed correctly). Output 4339\n
  • i is incremented and control flow enters level N + 1 again at (4)

在此之后情况重复 4340

我不确定为什么有些数字在没有换行符的序列之间打印出来,可能与 System.out.println的内部工作有关( )和它使用的缓冲区。

I'm not sure why some numbers are printed correclty between sequences without newlines, perhaps its related to internal work of System.out.println() and buffers it uses.

这篇关于在try-catch中混淆无限递归的输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆