Exception Handling

The exception handling features in the Java language provide a mechanism for gracefully recovering from a wide variety of unexpected situations in your code.

Some methods handle error conditions by returning an error code. For example, exists() method of the java.io.File class returns false if the file does not exist. However, this isn't good enough for us.

  • What if the method already returns something? Returning an error code may not make sense here.
  • What if we want to deal with the error differently depending on where we are in our program? For example, suppose we have a String that we would like to convert into an int. Even if we could figure out a way to return both the int value and a status flag that indicated success or failure, we may not know how to deal with the error quite yet… more on this later.

Exceptions

  • An exception represents a condition in which something unexpected/abnormal has occurred.
  • This condition may occur during the normal execution of a program, e.g.,
int x=Integer.parseInt("1.234");
  • When an exception occurs, the normal flow of the program is terminated.
  • Normal program flow is terminated by throwing and exception.
  • Once a exception has been thrown, program flow works backwards through the various method calls currently on the stack until the exception is caught.
  • An exception is caught by an exception handling routine.
  • We can provide exception handling routines or not.
  • If no exception handling routines are provided, the Java Virtual Machine will catch and handle the exception.
  • In order to catch an exception, we need to be watching for an exception to be thrown.
  • We watch for exceptions using a try block.

Consider the following code snippet:

String input = JOptionPane.showInputDialog(null, "How old are you (in years)");
int age;
try {
  age = Integer.parseInt(input);
  JOptionPane.showMessageDialog(null, "I'm guessing you'll be " + (age+1) + " next year");
} catch (NumberFormatException e) {
  JOptionPane.showMessageDialog(null, "Error!  You should enter an integer value");
}

If we enter something other than an integer, the program will display the error message, otherwise it will “guess” how old the user will be next year.

To summarize…

try block

  • Code between curly braces following a try statement is part of what we call a try block.
  • If, at any time, an exception is throw while we are in the try block, execution of the code within the try block is immediately halted. Program flow is transferred to the end of the try block.
  • Note: an exception can be encountered either by an explicit throw command within the try block or as a result of an un-handled exception thrown by a method which was called within the try block. In the above example, the exception was thrown by the parseInt method and was left unhandled.

catch blocks

  • Code between curly braces following a catch statement is part of what we call a catch block.
  • A catch block is executed if
    1. an exception has been encountered in the try block immediately proceeding it and
    2. the type of exception encountered matches the type of exception being caught.
  • The type of exception a catch block catches is specified in parentheses after the catch statement. In the above example, the catch block catches NumberFormatException type exceptions.
  • Only the first matching catch block after a try block will be executed.
  • If no exceptions were encountered during the execution of a try block, the catch block(s) after the try block are ignored. Program flow continues with the statement following the try-catch statement.
  • If an exception is encountered, but no matching catch block is present, program control reverts to the calling method.

Types of Exceptions

  • In order for an exception to be thrown, it must be an object from the Throwable class, or one of its subclasses.*
  • The Throwable class has two subclasses:
  • Recall that the type of exception being caught must be specified in the catch block's parameter list.
  • There are many different types of exceptions.

Brief Subclasses Overview

We will discuss subclasses more in the future, but, in short, a subclass is a specialization of a class. By way of analogy, a Dog is a type of animal.

  • Dog is not a particular animal (much like a class is not a particular object).
  • Spot is a specific instance of an animal of type Dog (much like an object is a particular instance of a class).
  • A Golden Retriever is a special type of Dog.
  • If Spot is a Golden Retriever, then Spot is a particular type (or subclass) of Dog.
  • Instances of Golden Retrievers share the the characteristics that all Dog instances share; however, they may have particular constraints on some of these characteristics.
  • For example, the set of potential colors that a Golden Retriever may be is more limited than the set of potential colors that a Dog may be.

Types of Exceptions revisited

Looking again at Throwable, Error, and Exception we can now conclude:

  • Error and Exception types are specializations of the Throwable type.
  • Exception has all of the characteristics (attributes/behaviors) of a Throwable object, but Exception may specialize (re-implement) some of these characteristics or add other characteristics that are shared by all Exception instances but don't apply to Throwable instances.
  • The java.lang package provides a number of subclasses (and subsubclasses, etc) of the Exception class.
  • Objects from any of these subclasses can be thrown.
  • The diagram below shows some of the types that can be thrown.

Handling Exceptions

  • When an object from the Error class is thrown, it represents a serious problem and normally should not be caught.
  • When an object from the Exception class, or one of its subclasses, is thrown, it typically should be caught and handled.
  • The type of exception a catch block catches is specified in parentheses after the catch statement.
    • A thrown exception will be caught if it is the same type or a subtype of the type specified in parentheses.
    • For example, if a NumberFormatException, it would be caught by the following catch block:
catch (Exception e) {
  // ...
}

since Exception is a superclass of NumberFormatException.

  • Once caught, methods from the Throwable class provide information about the exception that was thrown:
    • The getMessage() method returns a descriptive string.
    • The printStackTrace() method prints all of the methods on the stack, i.e., all of the still active methods called prior to encountering the exception.
  • Be sure to catch more specialized exception types (subclasses) first since once a matching catch block is found, all other catch blocks are ignored.
  • If an thrown exception is not caught, anywhere in the program, the Java Virtual Machine (JVM) catches it. The JVM handles exceptions by calling printStackTrace() and then terminating the program.

Recapping

Consider the following code:

String input = JOptionPane.showInputDialog(null, "How old are you (in years)");
int age;
try {
  age = Integer.parseInt(input);
  JOptionPane.showMessageDialog(null, "I'm guessing you'll be " + (age+1) + " next year");
} catch (NumberFormatException e) {
  JOptionPane.showMessageDialog(null, "Error!  You should enter an integer value");
} catch (RuntimeException e) {
  JOptionPane.showMessageDialog(null, "Error!  Some runtime exception other than NumberFormatException was thrown");
  JOptionPane.showMessageDialog(null, "Hint: " + e.getMessage());
  return;
}
 
JOptionPane.showMessageDialog(null, "No worries.  Either way we'll continue on with our program");
  • Recall that, if no exception occurs, all of the code except for the catch blocks will be executed.
  • If an exception is thrown while in the try block,
    • The first catch block will be executed if the exception thrown is of type NumberFormatException. Once the catch block finishes executing, program execution continues after the last catch block.
    • The second catch block will be executed if the exception thrown is of type RuntimeException or any subclass of RuntimeException other than NumberFormatException (because that exception would have already been caught by the first catch block). If the second catch block is executed, program control is returned to the calling method at the end of the catch block, so the “No worries” dialog will not be displayed.
    • If no catch block matches the exception thrown, execution of the current method is terminated and the exception is thrown to the calling method (which can either catch it or propagate the exception to the method that called it).
  • In addition to try and catch blocks, we have a finally block.
  • The finally block should contain code that must be executed regardless of whether an exception is thrown (or even if the try and/or catch blocks contain return statements).

finally block

String input = JOptionPane.showInputDialog(null, "How old are you (in years)");
int age;
try {
  age = Integer.parseInt(input);
  JOptionPane.showMessageDialog(null, "I'm guessing you'll be " + (age+1) + " next year");
} catch (NumberFormatException e) {
  JOptionPane.showMessageDialog(null, "Error!  You should enter an integer value");
} catch (RuntimeException e) {
  JOptionPane.showMessageDialog(null, "Error!  Some runtime exception other than NumberFormatException was thrown");
  JOptionPane.showMessageDialog(null, "Hint: " + e.getMessage());
  return;
} finally {
  JOptionPane.showMessageDialog(null, "I really want you to see this.");
}
 
JOptionPane.showMessageDialog(null, "No worries.  Either way we'll continue on with our program");
  • Adding the finally block in here means that the code within the finally block will be executed.
    • If a return statement is encountered prior to the finally block (in the try or a catch block doesn't matter), the code in the finally block is executed just prior to returning from the method.
    • If nothing is thrown, the code in the finally block executes immediately after the try block code executes.
    • If an exception is thrown and caught, the code in the finally block executes immediately after the catch block code executes.
    • If an exception is thrown but not caught, the code in the finally block executes immediately after the line of code that caused the exception to be thrown and then the exception is propagated back to the calling method.

throw statement

  • We can explicitly throw exceptions using the following to steps:
    1. Instantiate the appropriate Throwable object.
    2. throw a reference to that object.
  • An object is said to be a Throwable object if it is an instance of the Throwable class or one of Throwable's subclasses.
  • Exception is a subclass of Throwable.
  • Here is what it looks like in Java:
throw new Exception("Info about the exception");

Modifying the previous code to throw an exception if the user entered an age greater than 120 would look like this:

String input = JOptionPane.showInputDialog(null, "How old are you (in years)");
int age;
try {
  age = Integer.parseInt(input);
  if(age>120)
  {
    throw new Exception("Out of bounds");
  }
  JOptionPane.showMessageDialog(null, "I'm guessing you'll be " + (age+1) + " next year");
} catch (NumberFormatException e) {
  JOptionPane.showMessageDialog(null, "Error!  You should enter an integer value");
} catch (RuntimeException e) {
  JOptionPane.showMessageDialog(null, "Error!  Some runtime exception other than NumberFormatException was thrown");
  JOptionPane.showMessageDialog(null, "Hint: " + e.getMessage());
  return;
} finally {
  JOptionPane.showMessageDialog(null, "I really want you to see this.");
}
 
JOptionPane.showMessageDialog(null, "No worries.  Either way we'll continue on with our program");

Exception throwers

  • A method is said to be an exception thrower if it has the potential to throw an exception (directly or indirectly).
  • Such a method can be a:
    • Catcher – if it catches a thrown exception,
    • Propagator – if it leaves a exception uncaught (so that it propagates to the calling method, or
    • Both if it does some of each.

Unchecked Exception

  • Some exceptions are not allowed to propagate back to the VM, i.e., they must be caught by your code.
  • An checked exception is an exception that is checked at compile time.
  • Objects from the RuntimeException or one of its subclasses are unchecked exceptions.
    • Do not need to be caught by your code.
    • Are detected only at runtime.
  • Only RuntimeExceptions can be left unchecked.
  • In order to propagate a checked exception, the method propagating the exception must explicitly indicate that it may throw a checked exception.
    • To indicate that a method may throw a checked exception, the method's header must include a list of checked exceptions that it may throw.
    • The syntax makes use of the throws keyword as follows:
void someMethod() throws IOException {
  // ...
}
se1020/exceptionhandling.txt · Last modified: 2009/06/03 11:22 (external edit)
 

This website is not owned or managed by the Milwaukee School of Engineering.

© 2003-2010 Dr. Christopher C. Taylor, et. al. • Office: L-343 • Phone: 277-7339 • npǝ˙ǝosɯ@ɹolʎɐʇ • -> RSS <-