Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Exceptions to the programming rules, Part 2

Incorporate Java's throw-object/catch-object exception-handling technique into your Java programs

  • Print
  • Feedback

Page 2 of 8

I use the term error to distinguish JVM-related failure from program-related failure. Examples of error classes include java.lang.AssertionError, java.lang.ThreadDeath, and java.lang.VirtualMachineError. Not all error classes end with Error.

JVM errors belong to the unchecked exception category because a program can do little, if anything, to fix a JVM error. Also, don't create your own Error subclasses or try to handle JVM errors. The resulting program will probably prove unstable.

The StackTraceElement class

When your code must access stack-trace data (file names, source line numbers, method names, and so forth), that code can call Throwable's getStackTrace() method. The getStackTrace() method returns an array of references to java.lang.StackTraceElement objects -- where each object describes one stack frame in the stack trace.

Code can call StackTraceElement methods to access stack-trace data. Methods include getClassName(), getFileName(), getLineNumber(), getMethodName(), and isNativeMethod(). Each method returns information relevant to the stack frame associated with the StackTraceElement object.

What does stack-trace data look like? If you work with Sun Microsystems' SDK tools in a command-line environment, you probably see the stack-trace data produced by the printStackTrace() methods. If not, let's see if we can create some stack-trace data:

Listing 1. SortIntegerArray1.java

// SortIntegerArray1.java
class SortIntegerArray1
{
   public static void main (String [] args)
   {
      int numbers [] = { 22, 13, 5, 76, 3 };
      sort (numbers);
      for (int i = 0; i < numbers.length; i++)
           System.out.println (numbers [i]);
   }
   static void sort (int [] x)
   {
      for (int i = 0; i < x.length-1; i++)
           for (int j = 0; j < x.length-i; j++)
                if (x [j] > x [j+1])
                {
                    int temp = x [j];
                    x [j] = x [j+1];
                    x [j+1] = temp;
                }
   }
}


SortIntegerArray1 attempts to sort (order) a small integer array's contents into ascending order. However, the source code features a problem. After compiling that code and running the resulting class file, you encounter the following stack-trace data:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
        at SortIntegerArray1.sort(SortIntegerArray1.java:19)
        at SortIntegerArray1.main(SortIntegerArray1.java:9)


The stack-trace data identifies ArrayIndexOutOfBoundsException as the thrown exception object. Because ArrayIndexOutOfBoundsException signifies an unchecked exception arising from flawed code, the JVM creates an object from that class (behind the scenes) and searches for an appropriate exception handler. Although the program can provide that exception handler and receive the exception object, it chooses not to do so. When a program doesn't receive an exception object, the JVM's default exception handler accepts that responsibility: it receives that object and calls printStackTrace() to print a stack trace -- which is what you see above.

The two lines that start with at refer to a pair of stack frames on the method-call stack. Each stack frame describes a method that has not completed its execution when an exception occurs. From the previous output, you see that neither main() nor sort() (which main() called) is complete. Furthermore, you see the corresponding source code lines where main() called sort() and where sort()'s attempt to access an invalid array element led to the exception.

  • Print
  • Feedback

Resources