2
On page 359 of the Book: Java - How to Program - 10th Edition. Deitel explains the treatment of Java exceptions. It exemplifies the question with the following code:
public class UsingExceptions {
public static void main(String[] args) {
try {
throwException();
}
catch (Exception exception) { // exception thrown by throwException
System.err.println("4 - Exception handled in main");
}
doesNotThrowException();
}
// demonstrate try...catch...finally
public static void throwException() throws Exception {
try { // throw an exception and immediately catch it
System.out.println("1 - Method throwException");
throw new Exception(); // generate exception
}
catch (Exception exception) { // catch exception thrown in try
System.err.println(
"2 - Exception handled in method throwException");
throw exception; // rethrow for further processing
// code here would not be reached; would cause compilation errors
}
finally { // executes regardless of what occurs in try...catch
System.err.println("3 - Finally executed in throwException");
}
// code here would not be reached; would cause compilation errors
}
// demonstrate finally when no exception occurs
public static void doesNotThrowException() {
try { // try block does not throw an exception
System.out.println("5 - Method doesNotThrowException");
}
catch (Exception exception) { // does not execute
System.err.println(exception);
}
finally { // executes regardless of what occurs in try...catch
System.err.println("6 - Finally executed in doesNotThrowException");
}
System.out.println("7 - End of method doesNotThrowException");
}
}
In the book, Deitel agrees with me that the logical sequence of this code is:
1 - Method throwException
2 - Exception handled in method throwException
3 - Finally executed in throwException
4 - Exception handled in main
5 - Method doesNotThrowException
6 - Finally executed in doesNotThrowException
7 - End of method doesNotThrowException
However, when executing the code described in the book in Eclipse, Java inverts line 6 with line 5 and the result is like this:
1 - Method throwException
2 - Exception handled in method throwException
3 - Finally executed in throwException
4 - Exception handled in main
6 - Finally executed in doesNotThrowException
5 - Method doesNotThrowException
7 - End of method doesNotThrowException
That is, Java is calling the block finally
of the method doesNotThrowException
before entering the method. Someone can explain why?
Your console or even the operating system may be giving different priorities to
stdout
andstderr
. Have you tried replacing the calls toSystem.err
forSystem.out
?– Anthony Accioly
That’s what @Anthonyaccioly said. This "surprise behavior" of a block
finally
be executed before the corresponding blocktry
is an inversion of a well-established behavior that does not happen in Java under any circumstances. The execution offinally
(that only in a few very peculiar situations ceases to happen, as in the case of being preceded by aSystem.exit()
terminating the JVM immediately) is always, and by definition, subsequent to the normal completion (or abbreviated by exception release) of the blocktry
.– Piovezan
The @Anthony tip worked. Renaming all messages to System.err or System.out works. Searching better on err and out priorities, I found that this behavior is due to an Eclipse bug that has already been fixed. More details here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=32205. I am using Eclipse Photon 2018, so the inversion happens.
– Henry ABM