Skip to main content

Java

Recursion in Java: Examples Explained

·

Diagram showing a recursive method call chain in Java, each frame calling itself with a decremented parameter until reaching the base case

Recursion is a technique where a method calls itself to reduce a problem into smaller identical sub-problems. Java supports it natively, and understanding it unlocks solutions to problems that loops handle clumsily. This article covers how recursion works, how to set a base case that stops the calls, and two concrete examples: a countdown and a factorial calculator.

What recursion is and when to use it

A recursive method calls itself with a modified argument until a stopping condition (the base case) is met. Without a base case, the JVM keeps pushing frames onto the call stack until it throws a StackOverflowError.

Java methods can call themselves just like they call any other method. This lets you express a repeated operation in terms of itself, which suits problems like tree traversal, divide-and-conquer sorting, and combinatorial math. For flat loops over arrays, iteration is usually clearer. For problems with inherently nested or branching structure, recursion often produces shorter, more readable code.

How the call stack drives recursion

Each method call in Java gets its own stack frame containing local variables and the return address. When methodA() calls methodA() again, a new frame is pushed. When that inner call returns, the frame is popped and execution resumes in the outer call.

The StackOverflowError you get from an infinite recursive call is the JVM running out of stack space. Java does not perform tail-call optimization by default, so every active call consumes a frame. Keep that in mind for deep recursion on large inputs.

Countdown: the simplest recursive pattern

Here is a method with no base case. It compiles, but running it crashes immediately:

void countRecursion() {
    countRecursion();
}

Add a parameter and a base case:

void countRecursion(int number) {
    System.out.println(number);
    if (number > 0) {
        countRecursion(number - 1);
    }
}

Call it with countRecursion(10) and it prints 10, 9, 8, ... 1, 0, then returns. The if (number > 0) guard is the base case. When number reaches 0, no further recursive call is made, and the frames unwind.

The equivalent iterative version uses a for loop:

for (int i = 10; i >= 0; i--) {
    System.out.println(i);
}

Both produce identical output. The recursive version is more verbose here, but the pattern it demonstrates (call with modified argument, guard against base case) applies directly to the factorial example below.

Factorial: the canonical recursive calculation

The factorial of n is the product of every integer from 1 to n. Written as n!:

5! = 5 x 4 x 3 x 2 x 1 = 120

Notice that 5! = 5 x 4!, and 4! = 4 x 3!, and so on down to 1! = 1 and 0! = 1 by definition. That self-similar structure maps directly onto recursion:

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

You can write the same logic with the ternary operator:

int factorial(int n) {
    return (n == 0) ? 1 : n * factorial(n - 1);
}

Both versions return the same result. The ternary form is compact; the if/else form is easier to read when you are first working through the logic.

A complete runnable class:

public class RecursionExamples {

    static int factorial(int n) {
        return (n == 0) ? 1 : n * factorial(n - 1);
    }

    public static void main(String[] args) {
        System.out.println(factorial(5));  // 120
        System.out.println(factorial(0));  // 1
        System.out.println(factorial(10)); // 3628800
    }
}

3 rules for writing correct recursive methods

Every working recursive method in Java follows these three rules:

  1. Define the base case first. Write the stopping condition before writing the recursive call. If you cannot state the base case, you cannot write the recursion correctly.
  2. Move toward the base case on every call. Each recursive call must use an argument that is closer to triggering the base case. Countdown decrements number; factorial decrements n. A call that does not change the argument produces infinite recursion.
  3. Trust the smaller subproblem. Assume factorial(n - 1) returns the correct answer for n - 1, then use that result to compute the answer for n. You do not need to trace the entire call chain to reason about the current call.

Further reading

If you want to see recursion applied to data structures, Binary Search Trees in Java: Complete Guide walks through recursive insertion and traversal on a BST. Sorting Algorithms in Java: Step-by-Step covers merge sort, which uses the same divide-and-conquer recursive pattern as factorial but on arrays.

Need help with a Java assignment that uses recursion? Java Assignment Help connects you with developers who specialize in Java. Pay 50% upfront and 50% after you verify the code runs on your data.

Share: X / Twitter LinkedIn

Related articles

  • Java

    Java Swing Tutorial for Beginners

    Learn Java Swing from scratch: build your first window, wire button events, master five layout managers, and assemble a working calculator GUI.

    May 24, 2024

  • Java

    Advanced Java Data Management Techniques

    Master advanced Java data management: optimize data structures, handle concurrent access, tune memory, and use serialization and compression in real applications.

    May 3, 2024

  • Java

    Java File I/O: Read, Write, and Manage Files

    A practical guide to Java file I/O: streams, readers and writers, NIO Path and Files, buffering, serialization, and the exceptions that break file code.

    Oct 7, 2023

← All articles

Stuck on a programming assignment?

Get expert help in Java, C++, Python, JavaScript, SQL, and more. We deliver working code with a clear walkthrough so you can understand and defend it.