Java Reference
In-Depth Information
Solution 45: Exhausting Workout
If it weren't for the
TRy-finally
statement, it would be obvious what this program does: The
workHard
method calls itself recursively until the program throws a
StackOverflowError
, at which
point it terminates with an uncaught exception. The
try-finally
statement complicates matters.
When it tries to throw a
StackOverflowError
, the program ends up in a
finally
block in the
workHard
method, where it calls itself recursively. This seems like a prescription for an infinite
loop. Does the program loop indefinitely? If you run it, it appears to do exactly that, but the only
way to know for sure is to analyze its behavior.
The Java virtual machine limits the stack depth to some preset level. When this level is exceeded,
the VM throws a
StackOverflowError
. In order to make it easier to think about the behavior of the
program, let's pretend that the stack depth limit is much smaller than it really is: say, 3. Now let's
trace the execution.
The
main
method calls
workHard
, which calls itself recursively from its
try
block. Again it calls
itself from its
TRy
block. At this point, the stack depth is 3. When the
workHard
method attempts
once more to call itself from its
TRy
block, the call fails immediately with a
StackOverflowError
.
This error is caught in the innermost
finally
block, where the stack depth is already 3. From there
the
workHard
method attempts to call itself recursively, but the call fails with a
StackOverflowError
. This error is caught in the
finally
block one level up, where the stack depth
is 2. The call from this
finally
block has the same behavior as the call from the corresponding
try
block: It results eventually in a
StackOverflowError
. A pattern appears to be emerging, and indeed
it is.
The execution of
WorkOut
is illustrated in
Figure 5.1
. In this figure, calls to
workHard
are
represented by arrows, and executions of
workHard
are represented by circles. All calls are
recursive except for first one. Calls that result in an immediate
StackOverflowError
are
represented by arrows leading to gray circles. Calls from
TRy
blocks are represented by arrows
pointing down and to the left, and calls from
finally
blocks are represented by arrows pointing
down and to the right. The numbers on the arrows describe the sequence of calls.
Search WWH ::
Custom Search