Java бесконечная рекурсия и StackOverflowError - PullRequest
2 голосов
/ 01 февраля 2011

Извините, возможно, глупый вопрос, я новичок в Java.

Есть ли способ сделать бесконечную рекурсию в Java, такую ​​как:

public void sillyMethod()
{
    System.out.println(i);
    i++;
    sillyMethod();

}

он выбрасывает StackOverflowError, но я действительно хочу запускать его бесконечно. Есть ли способ сделать это?

Спасибо!

Ответы [ 4 ]

4 голосов
/ 01 февраля 2011

Да и нет, (но в основном нет! :)

Нет, это невозможно (самый разумный ответ): Для каждого вызова будет запись активации, помещенная в стек вызовов JVM.Это занимает ненулевой объем памяти, поэтому в какой-то момент у вас закончится память, и в этот момент будет выдано исключение StackOverflowException.

Да, это возможно (супер-теоретический ответ): В Спецификации языка Java нет ничего, что явно указывало бы на то, что в конечном итоге вы должны столкнуться с StackOverflowException.Это означает, что если вы найдете достаточно умный компилятор, он может быть достаточно умен, чтобы скомпилировать его в цикл .


С этим вопросом будет связан JVM поддерживает оптимизацию хвостового вызова. " Ответ на этот вопрос:" Нет, не сейчас, но это не исключено для будущих версий ".

1 голос
/ 01 февраля 2011

Как уже говорили другие, бесконечная рекурсия в конечном итоге приведет к переполнению стека, по крайней мере, в том, что касается реализации JVM.

Вы можете сделать что-то подобное, похожее на это, но избежать расширения стека, создав новый поток непосредственно перед тем, как старый умрет.

public class SillyClass implements Runnable {

private final int count;

public SillyClass(int cnt) {
    this.count = cnt;
}

public static void main(String[] args) {
    Thread t = new Thread(new SillyClass(0));
    t.start();
}

@Override
public void run() {
    System.out.println(count);
    Thread t = new Thread(new SillyClass(count + 1));
    t.start();
}

}

0 голосов
/ 01 февраля 2011

С Java вы не можете сделать это. Тем не менее, оптимизация хвостовых вызовов в языках (особенно функциональных, таких как Ocaml), вы можете сделать это, поскольку она внутренне превращает это в цикл.

0 голосов
/ 01 февраля 2011

Не рекурсивно, нет. Это подразумевает создание постоянно увеличивающегося стека вызовов, и в конечном итоге вам не хватит памяти для его хранения.

...