-2

The Java VM specification has the following statement under the topic of Abrupt Method Invocation Completion.

" A method invocation that completes abruptly never returns a value to its invoker."

How is then the finally block in this piece of code able to return a value?

public class WaitTest {

    public static void main(String[] args) {
        int j = methodThatExitsAbruptly(0);
        System.out.println(j);
    }

    public static int methodThatExitsAbruptly(int i) {
        try {
            if (i == 0) {
                throw new Exception();
            }
            return 1;

        } catch (Exception e) {
            throw e;
        } finally {
            return 2;
        }
    }
}
Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140

2 Answers2

2

The method is not considered to complete normally1. That is because a value is returned in the finally block, discarding any thrown exception.

JLS § 14.20.2 contains more info about the order of execution.

Remember to never ever return a value from the finally block. The reason that this was made possible was perhaps a design error within the Java language, and the reason it is still possible is possibly for backward-compatibility reasons.

See also:

PS: You can configure most IDE's to warn you about returning a value in the finally block.


1 JLS § 14.20.2 says:

If the finally block completes normally, then the try statement completes abruptly for reason R.

but a return is considered an abrupt completion.

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
0

Docs just feel contradicting each other (see actual answer below the horizontal line).

https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html has what you are asking about:

2.6.5. Abrupt Method Invocation Completion

[...] A method invocation that completes abruptly never returns a value to its invoker.

https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html speaks about completion of statements and blocks:

14.1. Normal and Abrupt Completion of Statements

[...] An abrupt completion always has an associated reason, which is one of the following:

  • [...]
  • A return with no value
  • A return with a given value

This also applies to blocks (14.2).

Then https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html says

8.4.7. Method Body

A method body is either a block of code that implements the method or simply a semicolon, indicating the lack of an implementation.

[...] If a method is declared to have a return type, then a compile-time error occurs if the body of the method can complete normally (§14.1).

TL;DR: abrupt completion does not provide a return value, return always completes (itself, the block and the method body) abruptly.


However what applies to your case is exactly one line below than what @MCEmperor quoted:

If the finally block completes normally, then the try statement completes abruptly for reason R.

If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).

(I have not even added the formatting, it is bold already on the page)

tevemadar
  • 12,389
  • 3
  • 21
  • 49