(Please use your browser's Back button to return)
What is an exception?
- An exception is an event that causes an interruption in the normal flow of a running program.
- In java, occurrance of an exception is represented by an object
- The object is of type Exception or a subclass of it.
When are exception objects created?
- when an exceptional condition is detected at runtime, the method that detects it creates the exception
object
- exceptional conditions, like other conditions, are detected using if-then-else.
- information can be placed into the exception object by using constructor arguments, as allowed
by the exception (sub)class
- many methods from Java API library classes are defined to create exception objects
- you can write methods that create exception objects
What happens once an exception object is created?
- It must be passed along the call chain until coming to a method which will handle it
- the call chain starts with the currently running method, then goes to the
method that called the currently running method, then goes to the method that called THAT method,
and so forth "up the line".
- if none of the methods along the call chain will handle it, it is reported to the user by the JVM and
program execution halts.
- The analogy used is to imagine the exception to be a ball, or better yet a "hot potato".
- The method that creates the exception object then throws it.
- A method interested in handling an exception contains code to catch it.
- throws and catch are Java keywords.
Is a method I write required to catch an exception thrown by a method it calls?
- No. (wait, there's more...)
- Exceptions actually come in two general flavors:
- unchecked exceptions require nothing of the caller
- these are of type RuntimeException or a subclass of it
- examples are IndexOutOfBoundsException and NullPointerException
- these kinds of exceptions can occur in nearly any method, so the caller
should not be obliged to handle them
- the caller is, however, allowed to handle such exceptions
- checked exceptions must either be caught or else re-thrown by the caller
- these are of all exception classes other than the unchecked ones.
- this requirement is enforced ("checked") by the compiler; a compiler error results if
not met
- In short, the caller of a method that throws a checked exception is required to either
catch it or throw it
How will I know whether a method I am calling requires me to catch to re-throw
an exception?
- Check the specification given in Method Detail of the method you want to call.
- If it contains a Throws: clause, then your method has to catch or throw
the exception type(s) described there.
- Note: this information is not contained in the Method Summary section.
- Note: unchecked exceptions are generally not documented in the specification. Don't worry about them.
Enough questions and lists! I need some examples!
Glad to oblige. Here are examples of:
- catching an exception thrown by a called method
- re-throwing (propagating) an exception thrown by a called method
- a method that creates and throws an exception
- a method that creates and throws a customized exception
- a method that both catches and throws an exception
Catching an exception thrown by a called method
/*
* Method to that simply returns true if given file exists and false otherwise
*/
public boolean fileExists(String fileName) {
try {
FileReader myReader = new FileReader(fileName);
} catch (FileNotFoundException e) {
return false;
}
return true;
}
Filereader is a class in the java.io package. The constructor
used here is defined to throw a FileNotFoundException (check
the documentation). Notice that the method call must occur in what is called a try block. Notice also that the catch is
written with a parameter list containing one parameter: the exception object e.
Re-throwing (propagating) an exception thrown by a called method
/*
* Method that returns value read from an existing FileReader
*/
public int getValue(FileReader myReader) throws IOException {
return myReader.read();
}
The read() method that FileReader inherits from InputStreamReader
is defined to throw an IOException if any error occurs during the read
operation (check the documentation).
If your method is not going to catch the exception, it must be defined to throw
it as shown here with the throws IOException clause.
A method that creates and throws an exception
/*
* Method to yield a secret code, provided the supplied password is correct.
* If the password is incorrect, it throws a general Exception.
*/
public int getCode(String password) throws Exception {
if (password.equals("where's my code?")) {
return 8397201;
} else {
throw new Exception("Invalid password: "+password);
}
}
Notice the method header must declare it may potentially throw an exception of type Exception.
Also notice that the Exception object is created and thrown in one statement, and that a
message explaining the exception can be passed to the Exception constructor.
A method that creates and throws a customized exception
/*
* Customized exception subclass, which must be stored in file BadPasswordException.java
*/
public class BadPasswordException extends Exception {
public BadPasswordException(String badPassword) {
super("Invalid password: "+badPassword);
}
}
/*
* Method to yield a secret code, provided the supplied password is correct.
* If the password is incorrect, it throws a BadPasswordException.
*/
public int getSecretCode(String password) throws BadPasswordException {
if (password.equals("where's my code?")) {
return 8397201;
} else {
throw new BadPasswordException(password);
}
}
Notice that the definition of the BadPasswordException class must be in a separate file
called BadPasswordException.java. This is of course true for any public Java class.
A method that both catches and throws an exception
/*
* Method that stores and returns value read from an existing FileReader
* If an IOException occurs, store MAX_VALUE then propagate the exception.
*/
public int setAndGetValue(FileReader myReader) throws IOException {
try {
this.value = myReader.read();
} catch (IOException e) {
this.value = Integer.MAX_VALUE;
throw e;
}
return this.value;
}
This technique is used when you want to propagate the exception to your client but still do some
cleanup before leaving. Notice the thrown exception is the same object that was just caught. It is
possible to throw a different exception object, or an object of a different exception type as well (the
throws clause would have to match or be type-compatible with the exception object type).
I think I understand the basics.
These examples cover the basic situations that arise, and are enough for an overview. The design choices made
concerning exceptions are usually based on the contractual relationship between the supplier (author) of
a class and its clients.