Java Reference
In-Depth Information
will refer to the exception object. If the
getAverage()
method returns normally, then the code
within the
catch
clause will not be executed.
So how did the caller of the
getAverage()
method know to wrap the method in a
try
and
have a
catch
for the
NotEnoughAtBatsException
? On the original design of exceptions in
Java (that is, the design that was seen in the 0.9 version of the language), the caller would just
have to know. If the caller failed to
catch
a thrown exception, then the next method in the call
stack would be checked to see whether there was a
catch
of the thrown exception. If all of
the methods in the call stack failed to
catch
the exception, the program would fall over in a
pile of bits. This isn't as odd as it seems; it is just the sort of exception mechanism used in the
C++ language.
But this didn't last when the first official release of the language (and the virtual machine)
came out. As of Java 1.0, the code shown earlier for
getAverage()
, which had no
throws
clause in the declaration, wouldn't compile. At that release, the exception mechanism was
changed so that any exception thrown by a method needed to be declared as part of the signa-
ture of that method. After all, if Java is really a type-safe language, then all the types that are
possible to return from a method should be part of that method's signature, and the compiler
should make sure that the calling code handles the returned type. Since a thrown exception
can be thought of as an alternate return value, it needs to be part of the signature.
So for the example code to actually compile, we would need to go back to the
Batter
interface
and change the declaration of the
getAverage()
method to:
float getAverage() throws NotEnoughAtBatsException;
Any exception that is thrown by a method must be declared as part of the signature of that
method. This tells the caller that it is possible that the exception may be thrown. In response,
the caller of such a method must have a
catch
clause that handles the exceptions that are
thrown.
The polymorphic nature of the Java type system comes into play here. If a method declares
that it can throw an exception of a particular class, that method may also throw an exception
of any subclass of that declared class. Similarly, if a
catch
clause is declared for an exception
of some type, it will also catch any thrown exception that is a subtype of the declared excep-
tion type.
Declaring that a method throws a particular type of exception tells the callers of the method
that the exception might be thrown. But it also tells the Java compiler that the exception can