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 ofRuntimeException
. - The type of the Expression is the class
Error
or a subclass ofError
.
- The type of the Expression is the class
- The
throw
statement is contained in thetry
block of atry
statement (§14.18) and the type of the Expression is assignable (§5.2) to the type of the parameter of at least onecatch
clause of thetry
statement. (In this case we say the thrown value is caught by thetry
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 thethrows
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).