Error Handling with Exceptions

Reading Assignment: Read 17.1-17.7 in Liang
Exercise: 17.3 in Liang

Review Question: What is generalization? What is abstraction?

What is an exception?

No matter what, mistakes happen

Ex: User enters the wrong input.
Ex: Programmer forgets to guard against an unexpected input value that crashes the program when it is run.
Ex: Input file does not exist.
Ex: out of bounds array index

... So...
Include code in programs to handle errors like these by writing exception handlers.

In Java, the exception handling approach separates normal code from error handling code in a program.

Exception handling is used when the system can recover from the problem. Recovery procedure = exception handler

Approach of exceptions:
1. The method in which the error occurs handles the problem.
2. The method in which the error occurs doesn't have enough information to fix the problem, so it hands the problem over to a higher context, the calling method.

Exception Handling: Language Features

Try Catch Blocks

"Try" to execute a step in a program and "catch" an exception if it occurs. (Approach 1)

Throw Statement

The throw statement creates an instance of class Exception or a subclass of Exception (like IOException). (Approach 2)

Example: Account class

The Exception Hierarchy

In Java, an exception object = instance of a specialization of the Throwable class

Exception constructors:
    - constructs an Exception with no specified detail message

Exception(String s)
    - constructs an Exception with detail message s

Two distinct kinds of exceptions:
1. Exceptions that derive from RuntimeException
             -RuntimeExceptions are thrown by the JVM.
2. Those that do not

General Rule:
A Runtime Exception occurs because you made a programming error.
Other types of exceptions occur because something bad (like an I/O error) happened to your perfectly nice program.

Some exceptions that inherit from RuntimeException
1. A bad cast
2. An out-of-bounds array access
3. A null pointer access

Exceptions that do not inherit from RuntimeException:
1. Trying to open a malformed URL
2. Trying to read from a nonexistent input file

Methods inherited from Throwable:
String getMessage()
    returns the error message string of this throwable object

void printStackTrace()
    prints this Throwable and its backtrace to the standard error stream

void printStackTrace(PrintWriter s)
    prints the Throwable object and its backtrace to specified PrintWriter

String toString()
    returns short description of throwable object

Examples with Exceptions

Exercise: Add:
to the catch block in the Account class.

Note that now the output indicates which method calls resulted in the exception:
Negative credit: -10 is not allowed
                   at ( 17)
                   at TestAccount.main ( 22)

Two choices for dealing with exceptions:
1. Advertise the exceptions a method throws (if the method doesn't catch the exception)

2. Catch (i.e. handle) the exception in the method

Ex: Header for readLine() method in class BufferedReader:
public String readLine() throws IOException

Throwing an Exception

Alternate version of Account class

public class Account
    // The credit method header specifies that it may throw an exception
    public void credit(long amount) throws RuntimeException
         if(amount < 0)
             throw new RuntimeException("Negative credit: " + amount + "is not allowed.");
         setBalance(getBalance() + amount);
    // Since the Exception is not caught, the program will terminate after throwing the exception and printing the stack trace.

When to advertise that your method throws an Exception:
AND your method does NOT handle the exception.

In these situations, you are leaving it to the calling method to fix the problem.


1. Throwing an Exception:

Ex: String readInfo(BufferedReader in) throws EOFException
   if(n < len) // file is shorter than expected
       throw new EOFException();

2. Catching Exceptions:
    // code that may contain throw statements
catch (ExceptionType e)
    // handler for this type of exception

How this code is executed:
If any of the code in the try block throws an exception of the type specified in the catch clause, then

If none of the code in the try block throws an exception, then the program skips the catch block.

Question: Should you handle an exception or pass it on to the calling method?
Answer: Catch exceptions that you know how to handle. Pass on the ones you don't know how to handle (and add a throws modifier to the method header).

Exercise:  The PrintEm class

Catching Multiple Exceptions

myReturnType  myMethod(...)

       // code that might throw exceptions
   catch(MalformedURLException e1)
       // handler for malformed URLs
    catch(IOException e2)
       //handler for I/O errors

Finally Clause

When your code throws an exception and doesn't handle it, it stops processing the remaining code in your method. If you have code that needs to be executed whether or not an exception is caught, use the finally clause.

String msgThatMustBePrinted = "vital message: ...";
    // code that might throw exceptions
catch(IOException e)
   // IO problems handled here

The program will print the message under all circumstances.

Three situations in which the program will execute the finally clause:
  1. Code throws no exceptions. Program executes all code in try block, then the finally clause code, and then the 1st line after try/catch block.
  2. Code throws an exception that is caught in a catch clause (e.g. IOException). So program executes all code in try block up to point at which exception is thrown - the remaining code in try block is skipped. Program executes code in matching catch clause, and code in finally clause is executed.
  3. Code throws an exception that is not caught by any catch clause. So program executes all code in try block until exception is thrown. Then the remaining code in the try block is skipped. Code in finally clause is executed, and exception is thrown back to calling method.

Examples: Circle classes