liveBook · Manning

Infinite recursion

As explained in 100 Java Mistakes and How to Avoid Them

Infinite recursion is recursion that continues without reaching a terminating condition and eventually exhausts available execution resources.

Infinite recursion repeatedly enters the same recursive path without satisfying its termination condition. Unlike finite recursion that eventually changes state and exits, it eventually exhausts available stack space; changing state is not enough if the condition remains unreachable. section 5.4.2

A mistaken delegation call

A button wrapper intends to delegate to its wrapped button, but calls onPressed() without the delegate qualifier. When enabled, the wrapper calls itself indefinitely. The same failure pattern can arise when recursive traversal encounters a cycle and does not record already-visited nodes. section 5.4.2 section 5.4.2

class ButtonWrapper implements Button {
  private final Button delegate;
  private boolean enabled;

  ButtonWrapper(Button delegate) {
    this.delegate = delegate;
  }

  public void setEnabled(boolean enabled) {
    this.enabled = enabled;
  }

  @Override
  public void onPressed() {
    if (!enabled) return;
    onPressed();    #1
  }
}

Inspect the focused Java wrapper example and the unqualified recursive call that should have delegated to the wrapped object. section 5.4.2

Prevent infinite recursion by:

  • Verifying that each recursive call can reach a valid exit condition and does not repeat the same relevant state. section 5.4.2
  • Tracking previously visited nodes when traversing structures that may contain cycles; rewrite tail recursion with loops where appropriate. section 5.5
  • Avoiding arbitrarily deep recursion and using heap-based structures such as ArrayDeque for non-tail recursion. section 5.5

How 100 Java Mistakes and How to Avoid Them covers it

How deep it goes
Explains state repetition, termination failure, stack consumption, delegation mistakes, and cyclic traversal, then gives prevention strategies.
Examples
Uses a faulty Java button wrapper and cyclic data-structure traversal as concrete failure cases.
What it assumes
Assumes familiarity with recursive methods, program state, Java stacks, and traversal of tree-like data structures.
What you can do after
Diagnose infinite recursion, add cycle tracking, verify termination, and replace unsuitable recursion with loops or heap-based structures.
How it connects
Links recursion with termination conditions, stack overflow, tree traversal, directed acyclic graphs, cycles, loops, and tail recursion.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Java Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.