Before you can catch an exception, some code somewhere must throw one.
Any code can throw an exception. This can be
throw
statementRegardless of what throws the exception, it's always thrown with the throw
statement.
The throw
statement requires a single argument: a throwable
object.
Throwable objects are instances of any subclass of the Throwable
class.
Here's an example of a throw statement.
throw someThrowableObject;
Now, let us look at the throw
statement in context.
The following pop()
method is taken from a class that implements a
common stack data structure. The method removes the top element from the stack and returns the object.
public Object pop() {
Object obj;
if (size == 0) {
throw new EmptyStackException();
}
obj = objectAt(size - 1);
setObjectAt(size - 1, null);
size--;
return obj;
}
The pop()
method checks to see if there is any element on the
stack.
If the stack is empty, that is, its size
is equal to 0
, pop()
instantiates a new EmptyStackException
object and throws it.
Note that the declaration of the pop()
method does not contain a
throws
clause because EmptyStackException
is not a checked exception, so pop is not required
to state that it might occur.
An application often responds to an exception by throwing another exception. In effect, the first exception causes the second exception. It is helpful to know when one exception causes another.
Chained exceptions allow us to do that!
The following example shows how to use a chained exception.
try {
// some code
} catch (IOException e) {
throw new Exception("Other IOException", e);
}
In this example, when an IOException
is caught, a new Exception
is created with the original cause attached and the
chain of exceptions is thrown up to the next higher level exception handler.
Here is a more extensive example of exception chaining.
public class Main {
public static void main(String[] args) {
try {
method1();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void method1() throws Exception {
try {
method2();
} catch (Exception e) {
throw new Exception("Exception thrown in method1()", e);
}
}
public static void method2() throws Exception {
try {
method3();
} catch (Exception e) {
throw new Exception("Exception thrown in method2()", e);
}
}
public static void method3() throws Exception {
throw new Exception("Exception thrown in method3()");
}
}
Note that we will then see the chained exceptions in the stack trace.
java.lang.Exception: Exception thrown in method1()
at UsingChainedExceptions.method1(UsingChainedExceptions.java:15)
at UsingChainedExceptions.main(UsingChainedExceptions.java:5)
Caused by: java.lang.Exception: Exception thrown in method2()
at UsingChainedExceptions.method2(UsingChainedExceptions.java:23)
at UsingChainedExceptions.method1(UsingChainedExceptions.java:13)
... 1 more
Caused by: java.lang.Exception: Exception thrown in method3()
at UsingChainedExceptions.method3(UsingChainedExceptions.java:28)
at UsingChainedExceptions.method2(UsingChainedExceptions.java:21)
... 2 more
The following are the methods and constructors in Throwable
that
support chained exceptions.
Throwable getCause()
returns the Throwable
that caused the current Throwable
.Throwable initCause(Throwable)
sets the current Throwable
's cause.Throwable(Throwable)
builds a new Throwable
and sets its cause.