-1

I have this method on Java 15:

int myMethod() throws MyException {
    try {   
        // do something
        return someInt;
    } catch (SQLException e) {
        throwingMethod(e);
    }
}

throwingMethod() wraps the SQLException into a MyException and throws the latter. Since the catch clause always throws a MyException, it is guaranteed that control will never reach the end of the catch clause.

Why then does the compiler complain about a "Missing return statement" in the catch clause? Is the best way to fix this to add an unreachable return statement like return 0; after the call to throwingMethod() just to make the compiler happy (I see it does)?

ARX
  • 1,040
  • 2
  • 14
  • 20

1 Answers1

2

and throws the latter

The compiler has no way to know this at the call site (*).

If you want to indicate that execution will not proceed beyond that line, declare your method as returning MyException, and throw the result of calling it:

MyException throwingMethod(SQLException e) throws MyException {
   // Either return or throw MyException.
   // Throwing is better if you need to guarantee it will actually be thrown,
   // and can't rely on it being thrown at the call site.
}

// In the catch:
throw throwingMethod(e);

(*) If you want to know why according to the spec, you can find it at JLS 8.4.7:

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

Your method has a return type (int), so it must not complete normally (without e.g. an exception or return).

But in JLS 14.22:

  • An expression statement can complete normally iff it is reachable.

That is, provided you can reach a method invocation (a kind of statement expression, hence a method invocation followed by a ; is an expression statement), it is considered that it can complete normally.

However:

  • A break, continue, return, throw, or yield statement cannot complete normally.

So you need the throw to make it not complete normally. I suppose you could use return instead; but throw is clearer in its meaning of "an exception will always occur on this line".

Andy Turner
  • 137,514
  • 11
  • 162
  • 243