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:
RuntimeException
or a subclass of RuntimeException
.
Error
or a subclass of Error
.
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.)
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).