EMZETT.
Login

Recursion

In short: A method that calls itself to break a problem down into smaller subproblems of the same kind — always needs a base case, otherwise it runs forever.

In more detail: Every recursive call places a new entry on the call stack; with no exit condition (base case), this eventually leads to a StackOverflowError. The classic textbook example is factorial calculation; many such cases can alternatively also be solved iteratively with a loop.

int factorial(int n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}

In Depth

int factorial(int n) {
    if (n <= 1) return 1;          // base case - stops the recursion
    return n * factorial(n - 1);   // recursive call with a smaller subproblem
}
 
// factorial(4) runs as follows:
// factorial(4) = 4 * factorial(3)
//              = 4 * (3 * factorial(2))
//              = 4 * (3 * (2 * factorial(1)))
//              = 4 * (3 * (2 * 1)) = 24
 
// If the base case is missing -> StackOverflowError
int infinite(int n) {
    return n * infinite(n - 1); // no exit - calls itself forever
}
 
// Fibonacci numbers recursively - illustrative but inefficient example
int fib(int n) {
    if (n <= 1) return n;
    return fib(n - 1) + fib(n - 2); // two recursive calls per step!
}

Every method call (including a recursive one) creates a new stack frame with its own local variables — for factorial(4), four such frames briefly stack on top of each other, until the recursion “unwinds” again and multiplies the results. The naive fib(n) example shows a common recursion problem: it recomputes the same intermediate results (e.g. fib(2)) exponentially many times, which becomes extremely slow for larger n — here either memoization (caching intermediate results) or an iterative loop solution helps, delivering the same result in linear time. As a rough rule of thumb: recursion is often more elegantly readable for problems that naturally break down into self-similar parts (tree structures, divide-and-conquer algorithms), while iterative solutions are almost always more memory- and performance-efficient.

See also: Methods, Loops, Algorithms