Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
java_language_specification_7.pdf
Скачиваний:
13
Добавлен:
21.03.2016
Размер:
3.11 Mб
Скачать

11.2

Compile-Time Checking of Exceptions

EXCEPTIONS

Asynchronous exceptions occur only as a result of:

An invocation of the (deprecated) stop method of class Thread or ThreadGroup.

The (deprecated) stop methods may be invoked by one thread to affect another thread or all the threads in a specified thread group. They are asynchronous because they may occur at any point in the execution of the other thread or threads.

An internal error or resource limitation in the Java virtual machine that prevents it from implementing the semantics of the Java programming language. In this case, the asynchronous exception that is thrown is an instance of a subclass of

VirtualMachineError.

Note that StackOverflowError, a subclass of VirtualMachineError, may be thrown synchronously by method invocation (§15.12.4.5) as well as asynchronously due to native method execution or Java virtual machine resource limitations. Similarly,

OutOfMemoryError, another subclass of VirtualMachineError, may be thrown synchronously during object creation (§12.5), array creation (§15.10.1, §10.6), class initialization (§12.4.2), and boxing conversion (§5.1.7), as well as asynchronously.

The Java SE platform permits a small but bounded amount of execution to occur before an asynchronous exception is thrown.

Asynchronous exceptions are rare, but proper understanding of their semantics is necessary if high-quality machine code is to be generated.

The delay noted above is permitted to allow optimized code to detect and throw these exceptions at points where it is practical to handle them while obeying the semantics of the Java programming language. A simple implementation might poll for asynchronous exceptions at the point of each control transfer instruction. Since a program has a finite size, this provides a bound on the total delay in detecting an asynchronous exception. Since no asynchronous exception will occur between control transfers, the code generator has some flexibility to reorder computation between control transfers for greater performance. The paper Polling Efficiently on Stock Hardware by Marc Feeley, Proc. 1993 Conference on Functional Programming and Computer Architecture, Copenhagen, Denmark, pp. 179-187, is recommended as further reading.

11.2 Compile-Time Checking of Exceptions

The Java programming language requires that a program contains handlers for checked exceptions which can result from execution of a method or constructor. For each checked exception which is a possible result, the throws clause for the method (§8.4.6) or constructor (§8.8.5) must mention the class of that exception or one of the superclasses of the class of that exception (§11.2.3).

306

EXCEPTIONS

Compile-Time Checking of Exceptions

11.2

This compile-time checking for the presence of exception handlers is designed to reduce the number of exceptions which are not properly handled. The checked exception classes (§11.1.1) named in the throws clause are part of the contract between the implementor and user of the method or constructor. The throws clause of an overriding method may not specify that this method will result in throwing any checked exception which the overridden method is not permitted, by its throws clause, to throw (§8.4.8.3).

When interfaces are involved, more than one method declaration may be overridden by a single overriding declaration. In this case, the overriding declaration must have a throws clause that is compatible with all the overridden declarations (§9.4.1).

The unchecked exception classes (§11.1.1) are exempted from compile-time checking.

Of the unchecked exception classes, error classes are exempted because they can occur at many points in the program and recovery from them is difficult or impossible. A program declaring such exceptions would be cluttered, pointlessly. Sophisticated programs may yet wish to catch and attempt to recover from some of these conditions.

Of the unchecked exception classes, runtime exception classes are exempted because, in the judgment of the designers of the Java programming language, having to declare such exceptions would not aid significantly in establishing the correctness of programs. Many of the operations and constructs of the Java programming language can result in exceptions at run-time. The information available to a Java compiler, and the level of analysis a compiler performs, are usually not sufficient to establish that such run-time exceptions cannot occur, even though this may be obvious to the programmer. Requiring such exception classes to be declared would simply be an irritation to programmers.

For example, certain code might implement a circular data structure that, by construction, can never involve null references; the programmer can then be certain that a NullPointerException cannot occur, but it would be difficult for a Java compiler to prove it. The theorem-proving technology that is needed to establish such global properties of data structures is beyond the scope of this specification.

We say that a statement or expression can throw a checked exception class E if, according to the rules in §11.2.1 and §11.2.2, the execution of the statement or expression can result in an exception of class E being thrown.

We say that a catch clause can catch its catchable exception class(es).

The catchable exception class of a uni-catch clause is the declared type of its exception parameter (§14.20).

The catchable exception classes of a multi-catch clause are the alternatives in the union that denotes the type of its exception parameter (§14.20).

307

11.2.1 Exception Analysis of Expressions

EXCEPTIONS

11.2.1 Exception Analysis of Expressions

A class instance creation expression (§15.9) can throw an exception class E iff either:

The expression is a qualified class instance creation expression and the qualifying expression can throw E; or

Some expression of the argument list can throw E; or

E is determined to be an exception class of the throws clause of the constructor that is invoked (§15.12.2.6); or

The class instance creation expression includes a ClassBody, and some instance initializer block or instance variable initializer expression in the ClassBody can throw E.

A method invocation expression (§15.12) can throw an exception class E iff either:

The method to be invoked is of the form Primary.Identifier and the Primary expression can throw E; or

Some expression of the argument list can throw E; or

E is determined to be an exception class of the throws clause of the method that is invoked (§15.12.2.6).

For every other kind of expression, the expression can throw an exception class E iff one of its immediate subexpressions can throw E.

11.2.2 Exception Analysis of Statements

A throw statement (§14.18) whose thrown expression has static type E and is not a final or effectively final exception parameter can throw E or any exception class that the thrown expression can throw.

For example, the statement throw new java.io.FileNotFoundException(); can throw java.io.FileNotFoundException only. Formally, it is not the case that it "can throw" a subclass or superclass of java.io.FileNotFoundException.

A throw statement whose thrown expression is a final or effectively final exception parameter of a catch clause C can throw an exception class E iff:

E is an exception class that the try block of the try statement which declares C can throw; and

E is assignment compatible with any of C's catchable exception classes; and

308

EXCEPTIONS

Exception Checking 11.2.3

E is not assignment compatible with any of the catchable exception classes of the catch clauses declared to the left of C in the same try statement.

A try statement (§14.20) can throw an exception class E iff either:

The try block can throw E, or an expression used to initialize a resource (in a try-with-resources statement) can throw E, or the automatic invocation of the close() method of a resource (in a try-with-resources statement) can throw E,

and E is not assignment compatible with any catchable exception class of any catch clause of the try statement, and either no finally block is present or the finally block can complete normally; or

Some catch block of the try statement can throw E and either no finally block is present or the finally block can complete normally; or

A finally block is present and can throw E.

An explicit constructor invocation statement (§8.8.7.1) can throw an exception class E iff either:

Some expression of the constructor invocation's parameter list can throw E; or

E is determined to be an exception class of the throws clause of the constructor that is invoked (§15.12.2.6).

Any other statement S can throw an exception class E iff an expression or statement immediately contained in S can throw E.

11.2.3 Exception Checking

It is a compile-time error if a method or constructor body can throw some exception class E when E is a checked exception class and E is not a subclass of some class declared in the throws clause of the method or constructor.

It is a compile-time error if a class variable initializer (§8.3.2) or static initializer (§8.7) of a named class or interface can throw a checked exception class.

It is a compile-time error if an instance variable initializer or instance initializer of a named class can throw a checked exception class unless that exception class or one of its superclasses is explicitly declared in the throws clause of each constructor of its class and the class has at least one explicitly declared constructor.

Note that no compile-time error is due if an instance variable initializer or instance initializer of an anonymous class (§15.9.5) can throw an exception class. In a named class, it is the responsibility of the programmer to propagate information about which exception classes can be thrown by initializers, by declaring a suitable throws clause on any explicit constructor declaration. This relationship between the checked exception classes thrown

309

11.2.3 Exception Checking

EXCEPTIONS

by a class's initializers and the checked exception classes declared by a class's constructors is assured implicitly for an anonymous class declaration, because no explicit constructor declarations are possible and a Java compiler always generates a constructor with a suitable throws clause for that anonymous class declaration based on the checked exception classes that its initializers can throw.

It is a compile-time error if a catch clause can catch checked exception class E1 and it is not the case that the try block corresponding to the catch clause can throw a checked exception class that is a subclass or superclass of E1, unless E1 is

Exception or a superclass of Exception.

It is a compile-time error if a catch clause can catch (§11.2) checked exception class E1 and a preceding catch block of the immediately enclosing try statement can catch E1 or a superclass of E1.

A Java compiler is encouraged to issue a warning if a catch clause can catch (§11.2) checked exception class E1 and the try block corresponding to the catch clause can throw checked exception class E2, a subclass of E1, and a preceding catch block of the immediately enclosing try statement can catch checked exception class E3 where E2 <:

E3 <: E1.

Example 11.2.3-1. Catching Checked Exceptions

import java.io.*;

class StaticallyThrownExceptionsIncludeSubtypes { public static void main(String[] args) {

try {

throw new FileNotFoundException();

}catch (IOException ioe) {

//Legal in Java SE 6 and 7. "catch IOException"

//catches IOException and any subtype.

}

try {

throw new FileNotFoundException();

//Statement "can throw" FileNotFoundException.

//It is not the case that statement "can throw"

//a subtype or supertype of FileNotFoundException.

}catch (FileNotFoundException fnfe) {

//Legal in Java SE 6 and 7.

}catch (IOException ioe) {

//Legal in Java SE 6 and 7, but compilers are

//encouraged to throw warnings as of Java SE 7.

//All subtypes of IOException that the try block

//can throw have already been caught.

}

try { m();

// Method m's declaration says "throws IOException".

310

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]