Java recursion and bounded factorial

Use a base case and validate the representable range.

Java
class Main {
    static long factorial(int n) {
        if (n < 0 || n > 20) throw new IllegalArgumentException("use 0 through 20");
        if (n == 0) return 1;
        return n * factorial(n - 1);
    }
    public static void main(String[] args) {
        System.out.println(factorial(4));
        if (factorial(0) != 1) throw new AssertionError("base");
    }
}
Output
24

Explanation

Each recursive call gets its own parameter and waits for the smaller call's result. factorial(0) returns one and stops descent.

This version accepts 0 through 20 because 20! fits in long while 21! does not. Rejecting values outside the contract avoids silently overflowing the result.

Explore the dry run
Guided walkthroughReady
1class Main {
2 static long factorial(int n) {
3 if (n < 0 || n > 20) throw new IllegalArgumentException("use 0 through 20");
4 if (n == 0) return 1;
5 return n * factorial(n - 1);
6 }
7 public static void main(String[] args) {
8 System.out.println(factorial(4));
9 if (factorial(0) != 1) throw new AssertionError("base");
10 }
11}

Follow the example

Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.

View the complete dry-run table
Prepared trace of the published program. Some rows group repeated iterations.
Step / lineWhat happensState after stepOutput so far
Start at 4.calls: 4
—
Descend through 3, 2, 1, and 0.calls: 4 -> 3 -> 2 -> 1 -> 0
—
Return the base result.factorial(0) = 1
—
Unwind with results 1, 2, 6, 24.factorial(4) = 24
—
Print the final result.factorial(4) = 24
24

Cost and common mistakes

O(n) time and O(n) stack frames for accepted n.

  • A long still has a fixed maximum value.
  • Recursive algorithms may exhaust stack space even when their numeric result fits; this bounded example has at most 21 calls.

Try it yourself

What happens for factorial(21)?

Reveal answer and reasoning

It throws IllegalArgumentException before attempting the multiplication.

Further reading