Очевидно, следующая рекурсия в Java вызовет ошибку переполнения стека:
public class XXX {
public static void main(String[] args) {
main(null);
}
}
Но что, если я поймаю эту ошибку и снова вызову функцию?
public class XXX {
public static void main(String[] args) {
try {
main(null);
} catch(StackOverflowError E) {
main(null);
}
}
}
как это работает тогда ??
Сообщите нам, каков результат
Ну, я пробовал это несколько раз, и это дало мне бесконечную рекурсию ...
Но действительно ли это разрешено в реальной программе?
@BoWang Почему бы и нет? Я полагаю, вы все равно будете бросать StackOverflowException, пока не израсходуете всю доступную память в куче.
Разве у вас не настоящая программа?
Хмммм не знаю. но поскольку это вызывает ошибку, я чувствую, что в этом типе рекурсии есть некоторые ограничения.
На самом деле это не сработает. Потому что второй вызов внутри try/catch не является try/catch. ;)
@AlexT. Он пойман, но на один уровень выше в стеке, он в конечном итоге закончится, но если стек разрешает вызовы n, я думаю, что это вызовет вызовы 2^n до того, как вызов верхнего уровня в main внутри улова верхнего уровня, наконец, выбросит и заставит программу выход.
Я не знаю этого, и у меня нет никаких доказательств этого, но я предполагаю, что если бы кто-то совершил такое очевидное злоупотребление практикой программирования, то результат был бы зависящим от платформы.
lol "злоупотребление" настолько точным
@BoWang Я бы порекомендовал почитать о том, почему нельзя ловить Error
Вот пример проблемы, связанной с платформой, которая может возникнуть. Поскольку вашей программе будет постоянно не хватать памяти, это может создать проблему в системном потоке, где в конечном итоге она не сможет выполнять некоторые критические функции из-за того, что вся доступная память будет уничтожена. Затем через какой-то непредсказуемый интервал ошибка может быть чем-то другим, кроме StackOverflowError. Я просто размышляю, потому что не знаю, насколько строго JVM определяет этот тип деталей реализации. Короче говоря, отлов StackOverflowError почти всегда - плохая идея.
Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что вы можете просто запустить этот код и выяснить это сами.




Программа в конечном итоге остановится, потому что вызов main(null) в блоке catch снова не перехватывает StackOverflowError. StackOverflowError в конечном итоге будет распространяться вниз по стеку.
Вы можете увидеть это, уменьшив размер стека с помощью опции -Xss108k JVM (наименьшее возможное значение на моей JVM) и изменив программу, чтобы выделить как можно больше в стеке, например. с использованием локальных переменных double:
public static void main(String... args) {
try {
double a00 = 0.13;
double a01 = 0.13;
...
double a99 = 0.13;
double b00 = 0.13;
double b01 = 0.13;
...
double k99 = 0.13;
main(null);
} catch (StackOverflowError ex) {
main(null);
}
}
Это приводит к тому, что StackOverflowError генерируется после 5 рекурсивных вызовов, и программа завершается.
Это не так много смысла, как бесконечный цикл, и это не очень хорошая идея. Если main вызвал что-либо еще, что могло бы вызывать другие методы, он будет вызывать случайные точки внутри main на каждой итерации в зависимости от глубины стека вызовов при запуске этого вызова main. В конечном итоге он также перестанет повторяться из-за того, что заметил @Alex T., хотя он будет работать очень долго.
@Paulpro спасибо, что указали на это, вы правы.
Нет проблем, хорошая демонстрация.
Почему бы тебе не попробовать?