Chained
Exceptions
Beginning with JDK 1.4, a
feature was incorporated into the exception subsystem: chained exceptions. The
chained exception feature allows you to associate another exception with an exception. This second exception
describes the cause of the first exception. For example, imagine a situation in
which a method throws an ArithmeticException
because of an attempt to divide by zero. However, the actual cause of the
problem was that an I/O error occurred, which caused the divisor to be set
improperly. Although the method must certainly throw an ArithmeticException, since that is the error that occurred, you
might also want to let the calling code know that the underlying cause was an
I/O error. Chained exceptions let you handle this, and any other situation in
which layers of exceptions exist.
To allow chained exceptions,
two constructors and two methods were added to Throwable. The constructors are shown here:
Throwable(Throwable causeExc) Throwable(String msg, Throwable causeExc)
In the first form, causeExc is the exception that causes
the current exception. That is, causeExc is
the underlying reason that an exception occurred. The second form allows you to specify a description at the same
time that you specify a cause exception. These two constructors have also been
added to the Error, Exception, and RuntimeException classes.
The chained exception methods
supported by Throwable are getCause( ) and initCause( ). These methods are shown in Table 10-3 and are
repeated here for the sake of
discussion.
Throwable getCause( )
Throwable initCause(Throwable
causeExc)
The getCause( ) method returns the exception that underlies the current
exception. If there is no underlying exception, null is returned. The initCause(
) method associates causeExc with
the invoking exception and returns a reference to the exception. Thus, you can associate a cause with an exception
after the exception has been created. However, the cause exception can be set
only once. Thus, you can call initCause(
) only once for each exception object. Furthermore, if the cause exception
was set by a constructor, then you can’t set it again using initCause( ). In general, initCause( ) is used to set a cause for
legacy exception classes that don’t support the two additional constructors
described earlier.
Here is an example that
illustrates the mechanics of handling chained exceptions:
// Demonstrate exception chaining.
class
ChainExcDemo {
static void demoproc() {
create an exception NullPointerException e = new NullPointerException("top layer");
add a cause
e.initCause(new
ArithmeticException("cause"));
throw e;
}
public static void main(String args[]) { try {
demoproc();
} catch(NullPointerException e) {
display top level exception
System.out.println("Caught: " + e);
display cause exception System.out.println("Original cause: " + e.getCause());
}
}
}
The output from the program
is shown here:
Caught: java.lang.NullPointerException: top
layer
Original cause: java.lang.ArithmeticException:
cause
In this example, the
top-level exception is NullPointerException.
To it is added a cause exception, ArithmeticException.
When the exception is thrown out of demoproc(
), it is caught by main( ).
There, the top-level exception is displayed, followed by the underlying
exception, which is obtained by calling getCause(
).
Chained exceptions can be
carried on to whatever depth is necessary. Thus, the cause exception can,
itself, have a cause. Be aware that overly long chains of exceptions may
indicate poor design.
Chained exceptions are not
something that every program will need. However, in cases in which knowledge of
an underlying cause is useful, they offer an elegant solution.
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2026 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.