Рекурсия в Java: понимание, примеры и компромиссы
Рекурсия в Java
Это руководство объясняет рекурсивные методы в Java, разбирает классический пример факториала и оценивает плюсы и минусы использования рекурсии.
В Java метод, вызывающий сам себя, называется рекурсивным, а сама техника — рекурсией. Простой реальный пример — два зеркала, установленные друг напротив друга: каждое отражение — это еще одно зеркальное отражение, повторяющееся до поглощения света.
Как работает рекурсия

На иллюстрации выше метод recurse() вызывается из main() — обычный вызов. Внутри recurse() тот же метод вызывает себя снова, создавая рекурсивный вызов. Для предотвращения бесконечного цикла каждый рекурсивный вызов должен включать условие завершения, обычно реализуемое с помощью оператора if…else.
Пример: Факториал числа с использованием рекурсии
class Factorial { static int factorial(int n) { if (n != 0) // условие завершения return n * factorial(n - 1); // рекурсивный вызов else return 1; } public static void main(String[] args) { int number = 4, result; result = factorial(number); System.out.println(number + " factorial = " + result); } }
Вывод:
4 factorial = 24
Метод factorial() вызывается из main() с аргументом number. Внутри factorial() строка
return n * factorial(n-1); заставляет метод вызвать себя с уменьшенным значением. Начиная с n = 4, вызовы последовательно: 4 → 3 → 2 → 1 → 0. Когда n достигает 0, условие if не выполняется, возвращая 1. Накопленное произведение затем распространяется обратно вверх по стеку вызовов к main().
Как выполняется программа факториала
На изображении ниже показана эволюция стека вызовов во время выполнения.

Преимущества и недостатки рекурсии
- Плюсы: Упрощает код для задач, естественным образом поддающихся рекурсивным паттернам (например, обход деревьев, комбинаторная генерация). Часто приводит к более коротким и читаемым реализациям.
- Минусы: Каждый рекурсивный вызов потребляет память стека; глубокая рекурсия может привести к переполнению стека. Рекурсивные решения обычно менее эффективны по памяти и могут работать медленнее итеративных аналогов.
В целом, рекурсия предлагает элегантные решения ценой более высокого потребления памяти и потенциальных накладных расходов на производительность. Во многих случаях, особенно при ограниченной глубине, этот компромисс оправдан.
Рекомендуемое чтение: Каковы преимущества и недостатки рекурсии?
java
- Освоение операторов Java: типы, синтаксис и практические примеры
- Интерфейсы в Java: концепции, реализация и лучшие практики
- Try-with-resources в Java: автоматическое управление ресурсами
- Аннотации в Java: типы, размещение и практические примеры
- Типы аннотаций в Java: предопределенные, кастомные и мета-аннотации
- Метод String.length() в Java: как получить длину строки (пример)
- Понимание String.charAt() в Java: синтаксис, возвращаемый тип, исключения и пример
- Освоение String.endsWith() в Java: проверка суффиксов строки с примерами
- Замена строк в Java: replace(), replaceAll() и replaceFirst() подробно
- Реверс строки в Java с использованием рекурсии — пошаговое руководство