When an exception object is created (i.e. when you new it), the Throwable constructor captures information about the context in which the exception was created. Later on, this information can be output in the form of a stacktrace, which can be used to help diagnose the problem that caused the exception in the first place.

Printing a stacktrace

Printing a stacktrace is simply a matter of calling the printStackTrace() method. For example:

try {
    int a = 0;
    int b = 0;
    int c = a / b;
} catch (ArithmeticException ex) {
    // This prints the stacktrace to standard output
    ex.printStackTrace();
}

The printStackTrace() method without arguments will print to the application’s standard output; i.e. the current System.out. There are also printStackTrace(PrintStream) and printStackTrace(PrintWriter) overloads that print to a specified Stream or Writer.

Notes:

  1. The stacktrace does not include the details of the exception itself. You can use the toString() method to get those details; e.g.
// Print exception and stacktrace
System.out.println(ex);
ex.printStackTrace();
  1. Stacktrace printing should be used sparingly; see http://stackoverflow.com/documentation/java/5381/java-pitfalls-exception-usage/19955/pitfall-excessive-or-inappropriate-stacktraces#t=201610200112090788291 . It is often better to use a logging framework, and pass the exception object to be logged.

Understanding a stacktrace

Consider the following simple program consisting of two classes in two files. (We have shown the filenames and added line numbers for illustration purposes.)

File: "Main.java"
1   public class Main {
2       public static void main(String[] args) {
3           new Test().foo();
4       }
5   }

File: "Test.java"
1   class Test {
2       public void foo() {
3           bar();
4       }
5   
6       public int bar() {
7           int a = 1;
8           int b = 0;
9           return a / b;
10      }

When these files are compiled and run, we will get the following output.

Exception in thread "main" java.lang.ArithmeticException: / by zero
        at Test.bar(Test.java:9)
        at Test.foo(Test.java:3)
        at Main.main(Main.java:3)

Let us read this one line at a time to figure out what it is telling us.

Line #1 tells us that the thread called “main” has terminated due to an uncaught exception. The full name of the exception is java.lang.ArithmeticException, and the exception message is “/ by zero”.

If we look up the javadocs for this exception, it says:

Thrown when an exceptional arithmetic condition has occurred. For example, an integer “divide by zero” throws an instance of this class.

Indeed, the message “/ by zero” is a strong hint that the cause of the exception is that some code has attempted to divide something by zero. But what?

The remaining 3 lines are the stack trace. Each line represents a method (or constructor) call on the call stack, and each one tells us three things: