递归调用Main [英] Call Main Recursively

查看:120
本文介绍了递归调用Main的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

public class Demo
{
    static int i=0;
    public static void main(String args[])
    {
        System.out.println("Hello"+(i++));
        main(args);
    }
}

在这个程序中,我用实例变量调用main。

In this program I am calling main with instance variable.

它可以正常运行到某些点但是在一些 Hello 打印之后它会给出 StackOverFlow 异常。

It runs properly upto some point but after some Hello prints it gives StackOverFlow Exception.

所以我把int放到它打印的次数。

So i put int to find how many times it gets printed.

我运行这个程序,它在 i = 4158 之后给出了Exception。

I run this program it gives Exception after i=4158.

但我运行了几次它给出了Exception at不同的价值我喜欢 4155,4124,4154 等。

But I run it several times it gives Exception at different value of i like 4155,4124,4154 etc.

我在这里知道 StackOverFlow 是由于坏的或无条件的递归调用而生成的。

As I know here StackOverFlow is generated because of bad or Unconditional recursive call.

我试图找出它,但不知道到底发生了什么。

I tried to figure out it but don't know what's exactly happening.

我想知道为什么在 4158 (或其他价值)之后?

I want to know why after 4158 (or other values) ?

它是依赖于我的系统还是依赖于我的程序?

Is it dependent on my System or is it dependent on My Program?

推荐答案

首先,你是影子你的 args 变量。在您的字段中定义的 args 不会被视为与您尝试递归调用的 args 相同在 main

First, you're shadowing your args variable. The args defined in your field isn't going to be regarded as the same args you're attempting to recursively call in main.

其次,递归最终耗尽,但这取决于你分配了多少内存应用程序,以及当时内存中的其他内容。如果你给它类似2GB(或更多)的空间,那么递归仍然会耗尽 - 但可能会有更高的值。

Second, the recursion eventually runs out, but that's dependent on how much memory you have allocated for the application, and what else is in memory at the time. If you gave it something like 2GB (or more) of space to work with, the recursion would still run out - but likely at a higher value.

作为for-例如,这是我用 -Xmx6G 运行时得到的结果:

As a for-instance, this is what I get when I run with -Xmx6G:

10791
10796
10789

这个数字可能因其他原因而有所不同我的操作系统正在运行。

The number is likely different due to what else my OS is running.

现在,对于原因它用完了:你的电话放在一个堆栈上,这不是记忆中有限的地方;它可以(有时确实)耗尽。

Now, for the reason it runs out: your calls are placed on a stack, which is not a finite place in memory; it can (and sometimes does) run out.

每次在Java中调用函数时,它都会进入堆栈。

Every time you call a function in Java, it goes onto the stack.

First time through:
 > main(0)

main()是总是被调用,所以它总是在堆栈的底部。

main() is always called, so it's always on the bottom of the stack.

如果我们再次调用 main() ,然后它的另一个调用放在堆栈上:

If we were to call main() again, then another call of it gets placed on the stack:

Second time through:
 > main(1)
 > main(0)

对于大多数简单的应用程序,只有少数几次调用(低于100)在调用堆栈上,它们的生命周期足够短,以至于它们不会在调用堆栈上持续很长时间。

For most simple applications, only a handful of calls (under 100) are ever put onto the call stack, and their lifecycle is short enough that they don't last on the call stack very long.

但是,你的应用程序是不同的,因为它缺少某些东西称为基本情况。这就是你用来决定停止递归的方法。

However, your application is different, since it's lacking something known as the base case. This is what you use to decide to stop recursing.

举例说明着名的阶乘函数,它表示:

Take, for example, the famous factorial function, which states:

      { 1          if n = 0
n! = <
      { n * (n-1)! if n > 0

我们有基本情况:如果 n = 0 ,那么我们不会继续进一步递减。否则,我们只会继续使用。

We have our base case: If n = 0, then we don't continue to recurse any further. Otherwise, we just keep on goin'.

以下是代码中的内容:

public long factorial(int n) {
    return n == 0 ? 1L : n * factorial(n-1);
}

一旦我到达我的基本案例,我就停止添加对堆栈 - 我实际上开始解析它们。

Once I've reached my base case, then I stop adding calls to the stack - I actually begin resolving them.

以下是 factorial(4)的示例:

> factorial(4)
  > factorial(3)
    > factorial(2)
      > factorial(1)
        > factorial(0)
        > 1
      > 1 * 1
    > 1 * 1 * 2
  > 1 * 1 * 2 * 3
> 1 * 1 * 2 * 3 * 4

所以,这就是说:如果你是要做一个递归函数,确保递归可以结束。否则,你将一直遇到这个问题。

So, this is all to say: if you're going to do a recursive function, make sure that the recursion can end. Otherwise, you'll be running into this issue all the time.

这篇关于递归调用Main的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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