This poor little program can't quite make up its mind. The
decision method returns true. But it also returns
false. What does it print? Is it even legal?
public class Indecisive { public static void main(String[] args) { System.out.println(decision()); } static boolean decision() { try { return true; } finally { return false; } } }
Solution 36: Indecision
You might think
that this program is illegal. After all, the decision method can't
return both TRue and false. If you tried it, you found that it
compiles without error and prints false. Why?
The reason is that in a
try-finally statement, the finally block is always executed
when control leaves the try block [JLS 14.20.2]. This is true
whether the try block completes normally or abruptly. Abrupt completion of a statement or block
occurs when it throws an exception, executes a break or
continue to an enclosing statement, or executes a return from
the method as in this program. These are called abrupt completions because they
prevent the program from executing the next statement in sequence.
When both the TRy block and the finally block
complete abruptly, the reason for the abrupt completion in the try
block is discarded, and the whole TRy-finally statement completes
abruptly for the same reason as the finally block. In this program, the
abrupt completion caused by the return statement in the TRy
block is discarded, and the TRy-finally statement completes
abruptly because of the return statement in the finally block.
Simply put, the program tries to return true but
finally it returns false.
Discarding the reason for abrupt completion is almost never
what you want, because the original reason for abrupt completion might be
important to the behavior of a program. It is especially difficult to understand
the behavior of a program that executes a break, continue, or
return statement in a TRy block only to have the statement's
behavior vetoed by a finally block.
In summary, every finally block should complete
normally, barring an unchecked exception. Never exit a
finally block with a return, break, continue, or
tHRow, and never allow a checked exception to propagate out of a
finally block.
For language designers, finally blocks should perhaps
be required to complete normally in the absence of unchecked exceptions. Toward
this end, a TRy-finally construct would require that the
finally block can complete normally [JLS
14.21]. A return, break, or continue statement that
transfers control out of a finally block would be disallowed, as would
any statement that could cause a checked exception to propagate out of the
finally block.
No comments:
Post a Comment
Your comments are welcome!