The try statement

14.20 The try statement

A try statement executes a block. If a value is thrown and the try statement has one or more catch clauses that can catch it, then control will be transferred to the first such catch clause. If the try statement has a finally clause, then another block of code is executed, no matter whether the try block completes normally or abruptly, and no matter whether a catch clause is first given control.

TryStatement: try Block Catches try Block Catches opt Finally

TryWithResourcesStatement Catches:

CatchClause Catches CatchClause

CatchClause: catch ( CatchFormalParameter ) Block

CatchFormalParameter: VariableModifiers opt CatchType VariableDeclaratorId

CatchType: ClassType ClassType | CatchType

Finally: finally Block

The Block immediately after the keyword try is called the try block of the try statement.

The Block immediately after the keyword finally is called the finally block of the try statement.

A try statement may have catch clauses, also called exception handlers.

A catch clause has exactly one parameter, which is called an exception parameter. The scope and shadowing of an exception parameter is specified in §6.3 and §6.4.

14.20 The try statement BLOCKS AND STATEMENTS

An exception parameter may denote its type as either a single class type or a union of two or more class types (called alternatives). The alternatives of a union are syntactically separated by | .

A catch clause whose exception parameter is denoted as a single class type is called a uni- catch clause.

A catch clause whose exception parameter is denoted as a union of types is called

a multi- catch clause. Each class type used in the denotation of the type of an exception parameter must

be the class Throwable or a subclass of Throwable , or a compile-time error occurs. It is a compile-time error if a type variable is used in the denotation of the type of

an exception parameter. It is a compile-time error if a union of types contains two alternatives D i and D j (i

≠ j) where D i is a subtype of D j (§4.10.2).

The declared type of an exception parameter that denotes its type with a single class type is that class type.

The declared type of an exception parameter that denotes its type as a union with alternatives D 1 | D 2 | ... | D n is lub( D 1 , D 2 , ..., D n ) (§15.12.2.7).

An exception parameter of a multi- catch clause is implicitly declared final if it is not explicitly declared final .

It is a compile-time error if an exception parameter that is implicitly or explicitly declared final is assigned to within the body of the catch clause.

In a uni- catch clause, an exception parameter that is not declared final (implicitly or explicitly) is considered effectively final if it never occurs within its scope as the left-hand operand of an assignment operator (§15.26).

An implicitly final exception parameter is final by virtue of its declaration, while an effectively final exception parameter is (as it were) final by virtue of how it is used. An exception parameter of a multi- catch clause is implicitly final, so will never occur as the left-hand operand of an assignment operator, but it is not considered effectively final.

If an exception parameter is effectively final (in a uni- catch clause) or implicitly final (in a multi- catch clause), then adding an explicit final modifier to its declaration will not introduce any compile-time errors. However, if the exception parameter of a uni- catch clause is explicitly declared final , then removing the final modifier may introduce compile-time errors. This is because the exception parameter, while still effectively final, can no longer be referenced by, for example, local classes. On the other hand, if there are no compile-time errors, it is possible to further change the program so that the exception parameter is re-assigned and no longer effectively final.

BLOCKS AND STATEMENTS The try statement 14.20

The exception types that a try statement can throw are specified in §11.2.2. The relationship of the exceptions thrown by the try block of a try statement and

caught by the catch clauses (if any) of the try statement is specified in §11.2.3. Exception handlers are considered in left-to-right order: the earliest possible catch

clause accepts the exception, receiving as its argument the thrown exception object, as specified in §11.3.

A multi- catch clause can be thought of as a sequence of uni- catch clauses. That is,

a catch clause whose exception parameter type is denoted as a union D 1 |D 2 | ... |D n is equivalent to a sequence of n catch clauses whose exception parameters have class types D 1 , D 2 , ..., D n , respectively. For example, the following code:

try { ... throws ReflectiveOperationException ... } catch (ClassNotFoundException | IllegalAccessException ex) {

... body ... }

is semantically equivalent to the following code: try {

... throws ReflectiveOperationException ... } catch (final ClassNotFoundException ex1) { ... body ... } catch (final IllegalAccessException ex2) { ... body ... }

whereby the multi- catch clause with two alternatives has been translated into two separate catch clauses, one for each alternative. A Java compiler is neither required nor recommended to compile a multi- catch clause by duplicating code in this manner, since it is possible to represent the multi- catch clause in a class file without duplication.

A finally clause ensures that the finally block is executed after the try block and any catch block that might be executed, no matter how control leaves the try block or catch block. Handling of the finally block is rather complex, so the two cases of a try statement with and without a finally block are described separately (§14.20.1, §14.20.2).

A try statement is permitted to omit catch clauses and a finally clause if it is a try -with-resources statement (§14.20.3).

14.20.1 Execution of try - catch BLOCKS AND STATEMENTS

14.20.1 Execution of try - catch

A try statement without a finally block is executed by first executing the try block. Then there is a choice:

• If execution of the try block completes normally, then no further action is taken and the try statement completes normally.

• If execution of the try block completes abruptly because of a throw of a value

V , then there is a choice: ◆ If the run-time type of V is assignment compatible with (§5.2) a catchable exception class of any catch clause of the try statement, then the first

(leftmost) such catch clause is selected. The value V is assigned to the parameter of the selected catch clause, and the Block of that catch clause is executed, and then there is a choice:

❖ If that block completes normally, then the try statement completes normally.

❖ If that block completes abruptly for any reason, then the try statement completes abruptly for the same reason.

◆ If the run-time type of V is not assignment compatible with a catchable exception class of any catch clause of the try statement, then the try

statement completes abruptly because of a throw of the value V . • If execution of the try block completes abruptly for any other reason, then the

try statement completes abruptly for the same reason.

Example 14.20.1-1. Catching An Exception

class BlewIt extends Exception { BlewIt() { } BlewIt(String s) { super(s); }

} class Test {

static void blowUp() throws BlewIt { throw new BlewIt(); }

public static void main(String[] args) {

try { blowUp(); } catch (RuntimeException r) {

System.out.println("Caught RuntimeException"); } catch (BlewIt b) {

System.out.println("Caught BlewIt");

BLOCKS AND STATEMENTS Execution of try - finally and try - catch - finally 14.20.2

Here, the exception BlewIt is thrown by the method blowUp . The try-catch statement in the body of main has two catch clauses. The run-time type of the exception is BlewIt which is not assignable to a variable of type RuntimeException , but is assignable to a variable of type BlewIt , so the output of the example is:

Caught BlewIt

14.20.2 Execution of try - finally and try - catch - finally

A try statement with a finally block is executed by first executing the try block. Then there is a choice:

• If execution of the try block completes normally, then the finally block is executed, and then there is a choice:

◆ If the finally block completes normally, then the try statement completes normally.

◆ If the finally block completes abruptly for reason S , then the try statement completes abruptly for reason S .

• If execution of the try block completes abruptly because of a throw of a value

V , then there is a choice: ◆ If the run-time type of V is assignment compatible with a catchable exception class of any catch clause of the try statement, then the first (leftmost) such

catch clause is selected. The value V is assigned to the parameter of the selected catch clause, and the Block of that catch clause is executed. Then there is a choice:

❖ If the catch block completes normally, then the finally block is executed. Then there is a choice:

✦ If the finally block completes normally, then the try statement

completes normally. ✦ If the finally block completes abruptly for any reason, then the try

statement completes abruptly for the same reason. ❖ If the catch block completes abruptly for reason R , then the finally block

is executed. Then there is a choice: ✦ 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).

14.20.2 Execution of try - finally and try - catch - finally BLOCKS AND STATEMENTS

◆ If the run-time type of V is not assignment compatible with a catchable exception class of any catch clause of the try statement, then the finally

block is executed. Then there is a choice: ❖ If the finally block completes normally, then the try statement completes

abruptly because of a throw of the value V .

❖ If the finally block completes abruptly for reason S , then the try statement completes abruptly for reason S (and the throw of value V is discarded and

forgotten). • If execution of the try block completes abruptly for any other reason R , then the

finally block is executed, and then there is a choice: ◆ 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).

Example 14.20.2-1. Handling An Uncaught Exception With finally class BlewIt extends Exception {

BlewIt() { } BlewIt(String s) { super(s); }

} class Test {

static void blowUp() throws BlewIt {

throw new NullPointerException();

} public static void main(String[] args) {

try { blowUp(); } catch (BlewIt b) {

System.out.println("Caught BlewIt"); } finally {

System.out.println("Uncaught Exception");

This program produces the output: Uncaught Exception

Exception in thread "main" java.lang.NullPointerException

at Test.blowUp(Test.java:7) at Test.main(Test.java:11)

The NullPointerException (which is a kind of RuntimeException ) that is thrown by method blowUp is not caught by the try statement in main , because a

BLOCKS AND STATEMENTS try -with-resources 14.20.3

NullPointerException is not assignable to a variable of type BlewIt . This causes the finally clause to execute, after which the thread executing main , which is the only thread of the test program, terminates because of an uncaught exception, which typically results in printing the exception name and a simple backtrace. However, a backtrace is not required by this specification.

The problem with mandating a backtrace is that an exception can be created at one point in the program and thrown at a later one. It is prohibitively expensive to store a stack trace in an exception unless it is actually thrown (in which case the trace may be generated while unwinding the stack). Hence we do not mandate a back trace in every exception.

14.20.3 try -with-resources

A try -with-resources statement is parameterized with variables (known as resources) that are initialized before execution of the try block and closed automatically, in the reverse order from which they were initialized, after execution of the try block. catch clauses and a finally clause are often unnecessary when resources are closed automatically.

TryWithResourcesStatement: try ResourceSpecification Block Catches opt Finally opt

ResourceSpecification: ( Resources ; opt )

Resources: Resource Resource ; Resources

Resource: VariableModifiers opt Type VariableDeclaratorId = Expression

A ResourceSpecification declares one or more local variables with initializer expressions to act as resources for the try statement.

A resource declared in a ResourceSpecification is implicitly declared final (§4.12.4) if it is not explicitly declared final .

The type of a variable declared in a ResourceSpecification must be a subtype of AutoCloseable , or a compile-time error occurs.

The scope and shadowing of a variable declared in a ResourceSpecification is specified in §6.3 and §6.4.

14.20.3 try -with-resources BLOCKS AND STATEMENTS

It is a compile-time error for a ResourceSpecification to declare two variables with the same name.

Resources are initialized in left-to-right order. If a resource fails to initialize (that is, its initializer expression throws an exception), then all resources initialized so far by the try -with-resources statement are closed. If all resources initialize successfully, the try block executes as normal and then all non-null resources of the try -with- resources statement are closed.

Resources are closed in the reverse order from that in which they were initialized.

A resource is closed only if it initialized to a non-null value. An exception from the closing of one resource does not prevent the closing of other resources. Such an exception is suppressed if an exception was thrown previously by an initializer, the try block, or the closing of a resource.

A try -with-resources statement with a ResourceSpecification clause that declares multiple resources is treated as if it were multiple try -with-resources statements, each of which has a ResourceSpecification clause that declares a single Resource. When a try -with-resources statement with n Resources (n > 1) is translated, the result is a try -with-resources statement with n-1 Resources. After n such translations, there are n nested try - catch - finally statements, and the overall translation is complete.

14.20.3.1 Basic try -with-resources

A try -with-resources statement with no catch clauses or finally clause is called

a basic try -with-resources statement. The meaning of a basic try -with-resources statement:

try (VariableModifiers opt R Identifier = Expression ...)

Block

is given by the following translation to a local variable declaration and a try - catch - finally statement:

BLOCKS AND STATEMENTS try -with-resources 14.20.3

{ final VariableModifiers_minus_final R Identifier = Expression; Throwable #primaryExc = null;

try ResourceSpecification_tail Block catch (Throwable #t) { #primaryExc = #t; throw #t;

} finally { if (Identifier != null) { if (#primaryExc != null) { try {

Identifier.close(); } catch (Throwable #suppressedExc) {

#primaryExc.addSuppressed(#suppressedExc); } } else { Identifier.close(); } } } }

VariableModifiers opt _minus_final is defined as VariableModifiers opt without final , if present.

#t , #primaryExc , and #suppressedExc are automatically generated identifiers that are distinct from any other identifiers (automatically generated or otherwise) that are in scope at the point where the try -with-resources statement occurs.

resource, then ResourceSpecification_tail is empty (and the try - catch - finally statement is not itself a try -with-resources statement).

If the ResourceSpecification

declares

one

If the ResourceSpecification declares n > 1 resources, then ResourceSpecification_tail consists of the 2nd, 3rd, ..., n'th resources declared in ResourceSpecification, in the same order (and the try - catch - finally statement is itself a try -with-resources statement).

Reachability and definite assignment rules for the basic try -with-resources statement are implicitly specified by the translation above.

In a basic try -with-resources statement that manages a single resource: • If the initialization of the resource completes abruptly because of a throw of a

value V , then the try -with-resources statement completes abruptly because of a

throw of the value V .

14.20.3 try -with-resources BLOCKS AND STATEMENTS

• If the initialization of the resource completes normally, and the try block completes abruptly because of a throw of a value V , then:

◆ If the automatic closing of the resource completes normally, then the try -with- resources statement completes abruptly because of a throw of the value V .

◆ If the automatic closing of the resource completes abruptly because of a throw of a value V2 , then the try -with-resources statement completes abruptly

because of a throw of value V with V2 added to the suppressed exception list of V .

• If the initialization of the resource completes normally, and the try block completes normally, and the automatic closing of the resource completes abruptly because of a throw of a value V , then the try -with-resources statement

completes abruptly because of a throw of the value V . In a basic try -with-resources statement that manages multiple resources: • If the initialization of a resource completes abruptly because of a throw of a

value V , then: ◆ If the automatic closings of all successfully initialized resources (possibly

zero) complete normally, then the try -with-resources statement completes

abruptly because of a throw of the value V .

◆ If the automatic closings of all successfully initialized resources (possibly zero) complete abruptly because of throw s of values V1 ... Vn , then the try -

with-resources statement completes abruptly because of a throw of the value V with any remaining values V1 ... Vn added to the suppressed exception list of V .

• If the initialization of all resources completes normally, and the try block completes abruptly because of a throw of a value V , then:

◆ If the automatic closings of all initialized resources complete normally, then the try -with-resources statement completes abruptly because of a throw of

the value V .

◆ If the automatic closings of one or more initialized resources complete abruptly because of throw s of values V1 ... Vn , then the try -with-resources statement

completes abruptly because of a throw of the value V with any remaining values V1 ... Vn added to the suppressed exception list of V .

• If the initialization of every resource completes normally, and the try block completes normally, then:

◆ If one automatic closing of an initialized resource completes abruptly because of a throw of value V , and all other automatic closings of initialized resources

BLOCKS AND STATEMENTS Unreachable Statements 14.21

complete normally, then the try -with-resources statement completes abruptly

because of a throw of the value V .

◆ If more than one automatic closing of an initialized resource completes abruptly because of throw s of values V1 ... Vn , then the try -with-resources

statement completes abruptly because of a throw of the value V1 with any remaining values V2 ... Vn added to the suppressed exception list of V1 (where

V1 is the exception from the rightmost resource failing to close and Vn is the exception from the leftmost resource failing to close).

14.20.3.2 Extended try -with-resources

A try -with-resources statement with at least one catch clause and/or a finally clause is called an extended try -with-resources statement.

The meaning of an extended try -with-resources statement:

try ResourceSpecification Block Catches opt Finally opt

is given by the following translation to a basic try -with-resources statement (§14.20.3.1) nested inside a try - catch or try - finally or try - catch - finally statement:

try { try ResourceSpecification Block } Catches opt Finally opt

The effect of the translation is to put the ResourceSpecification "inside" the try statement. This allows a catch clause of an extended try -with-resources statement to catch an exception due to the automatic initialization or closing of any resource.

Furthermore, all resources will have been closed (or attempted to be closed) by the time the finally block is executed, in keeping with the intent of the finally keyword.