Найти в Дзене
Иван

Рекурсия и StackOverflowException

Всем привет, пока думаю о чем именно теперь писать на канале, решил разобрать одну интересную тему, которая впрочем тоже встречается на курсах. Спешу представить: её величество, Рекурсия! Что такое "рекурсия"? Смотри "рекурсия" (с) Для начала пойдемте в наш любимый гугл и узнаем, что же такое рекурсия, вот здесь довольно неплохо разбирается тема и классический пример с факториалом. Но мы конечно же попробуем разобрать максимально доступно, может быть даже местами слишком :). И начнем с самого простого определения: Рекурсия, это вызов методом самого себя. Если рассмотреть на примере в лоб, то это примерно так: Запустите у себя в среде разработке такой код, и получите в консоле StackOverflowException, наверное самое известное исключение после NPE, благодаря одноименному сайту. Почему получите исключение? Все достаточно просто. Рекурсия устроена таким образом, что она начинает отрабатывать только когда дойдет до нижнего уровня, он же условие выхода. До тех пор, вся информация которая

Всем привет, пока думаю о чем именно теперь писать на канале, решил разобрать одну интересную тему, которая впрочем тоже встречается на курсах. Спешу представить: её величество, Рекурсия!

Что такое "рекурсия"? Смотри "рекурсия" (с)

Для начала пойдемте в наш любимый гугл и узнаем, что же такое рекурсия, вот здесь довольно неплохо разбирается тема и классический пример с факториалом.

Но мы конечно же попробуем разобрать максимально доступно, может быть даже местами слишком :). И начнем с самого простого определения: Рекурсия, это вызов методом самого себя. Если рассмотреть на примере в лоб, то это примерно так:

Запустите у себя в среде разработке такой код, и получите в консоле StackOverflowException, наверное самое известное исключение после NPE, благодаря одноименному сайту.

Почему получите исключение? Все достаточно просто. Рекурсия устроена таким образом, что она начинает отрабатывать только когда дойдет до нижнего уровня, он же условие выхода. До тех пор, вся информация которая будет изменяться внутри метода да и просто информация о вызове метода, все это будет храниться в стеке, области памяти java. По сути в оперативной памяти компьютера. А так как условия выхода у нас нет, то мы бесконечно будем уходить "вниз" , точнее до тех пор, пока у нас будет хватать памяти.

Что же делать. Конечно же обеспечить это самое условие выхода. Например вот так:

-2

Мы добавили условие, которое говорит нам, вызывать метод только если переданное в параметр число будет больше нуля. То есть, если число будет меньше или равно нулю, мы просто выйдем из метода.

Как вы можете догадаться, передав положительное число в параметры метода, мы также добьемся нашего любимого StackOverflowException.

И тут мы доходим до следующего необходимого условия правильной рекурсии - шаг рекурсии. Для того, чтобы правильно не просто запустить, но и выйти из рекурсии необходимо сделать что-то вроде этого:

-3

Для наглядности я добавил вывод на экран. Как вы поняли, шаг рекурсии это n--;

Теперь, при запуске программы, каждый раз заходя в метод, мы будем вычитать единицу из нашего числа и так до тех пор, пока не дойдем до 0. Но ноль успеет вывестись на экран так как у нас System.out.println(n); стоит выше вызова метода и в консоле мы увидим это:

10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0

Вот собственно говоря и есть самый простой и банальный пример рекурсии. Можете поэкспериментировать с расположением n--, подаваемыми в метод числами и условиями в if. Но тут есть еще один небольшой но интересный момент.

Если вы перенесете System.out.println(n); после if-а, между 8-й и 9-й строчкой, то обнаружите, что вывод будет не просто от нуля до девяти (думаю это понятно почему), а в самом начале будет 2 нуля.

Вопрос для любителей порассуждать и писать комментарии: Почему будет 2 нуля вначале?

Всем отличного дня, надеюсь материал был полезным! Пишите в комментарии, что думаете, задавайте вопросы ну и просто общайтесь!

-4