14.16 The throw Statement

A throw statement causes an exception (§11) to be thrown. The result is an immediate transfer of control (§11.3) that may exit multiple statements and multiple constructor, static and field initializer evaluations, and method invocations until a try statement (§14.18) is found that catches the thrown value. If no such try statement is found, then execution of the thread (§17, §20.20) that executed the throw is terminated (§11.3) after invocation of the UncaughtException method (§20.21.31) for the thread group to which the thread belongs.

ThrowStatement:
throw Expression ;

The Expression in a throw statement must denote a variable or value of a reference type which is assignable (§5.2) to the type Throwable, or a compile-time error occurs. Moreover, at least one of the following three conditions must be true, or a compile-time error occurs:

  • The exception is not a checked exception (§11.2)-specifically, one of the following situations is true:
    • The type of the Expression is the class RuntimeException or a subclass of RuntimeException.
    • The type of the Expression is the class Error or a subclass of Error.
  • The throw statement is contained in the try block of a try statement (§14.18) and the type of the Expression is assignable (§5.2) to the type of the parameter of at least one catch clause of the try statement. (In this case we say the thrown value is caught by the try statement.)
  • The throw statement is contained in a method or constructor declaration and the type of the Expression is assignable (§5.2) to at least one type listed in the throws clause (§8.4.4, §8.6.4) of the declaration.

A throw statement first evaluates the Expression. If the evaluation of the Expression completes abruptly for some reason, then the throw completes abruptly for that reason. If evaluation of the Expression completes normally, producing a value V, then the throw statement completes abruptly, the reason being a throw with value V.

It can be seen, then, that a throw statement always completes abruptly.

If there are any enclosing try statements (§14.18) whose try blocks contain the throw statement, then any finally clauses of those try statements are executed as control is transferred outward, until the thrown value is caught. Note that abrupt completion of a finally clause can disrupt the transfer of control initiated by a throw statement.

If a throw statement is contained in a method declaration, but its value is not caught by some try statement that contains it, then the invocation of the method completes abruptly because of the throw.

If a throw statement is contained in a constructor declaration, but its value is not caught by some try statement that contains it, then the class instance creation expression (or the method invocation of method newInstance of class Class) that invoked the constructor will complete abruptly because of the throw.

If a throw statement is contained in a static initializer (§8.5), then a compile-time check ensures that either its value is always an unchecked exception or its value is always caught by some try statement that contains it. If, despite this check, the value is not caught by some try statement that contains the throw statement, then the value is rethrown if it is an instance of class Error or one of its subclasses; otherwise, it is wrapped in an ExceptionInInitializerError object, which is then thrown (§12.4.2).

By convention, user-declared throwable types should usually be declared to be subclasses of class Exception, which is a subclass of class Throwable (§11.5, §20.22).