Chapter 14

Exception Handling


Chapter Goals

Error Codes

Exceptions

Exceptions

public class BankAccount 
{
public void withdraw(double amount)
{
if (amount > balance)
throw new IllegalArgumentException(
"Amount exceeds balance");
balance = balance - amount;
}
...
}

Hierarchy of Exception Classes


Syntax 14.1: Throwing an Exception

  throw exceptionObject;

Example:

 
throw new IllegalArgumentException();

Purpose:

To throw an exception and transfer control to a handler for this exception type

Checked Exceptions

Checked and Unchecked Exceptions



Exception Specifications

public class Coin 
{
public void read(BufferedReader in) throws IOException
{
value = Double.parseDouble(in.readLine());
name =in.readLine();
}
...
}

Exception Specifications

Syntax 14.2: Exception Specification

  accessSpecifier returnType methodName(parameterType parameterName, . . .)
throws ExceptionClass, ExceptionClass . . .

Example:

  public void read(BufferedReader in) throws IOException

Purpose:

To indicate the checked exceptions that a method can throw

Designing Your Own Exception Types

Designing Your Own Exception Types

public class InsufficientFundsException 
extends RuntimeException
{
public InsufficientFundsException()
{
}
 
public InsufficientFundsException(String reason)
{
super(reason);
}
}

Catching Exceptions

try 
{
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
System.out.println("How old are you?");
String inputLine = in.readLine();
int age = Integer.parseInt(inputLine);
age++;
System.out.println("Next year,you'll be " + age);
}
catch (IOException exception)
{
System.out.println("Input/output error " +exception);
}
catch (NumberFormatException exception)
{
System.out.println("Input was not a number");
}

Catching Exceptions

Syntax 14.3: General Try Block

 
try 
{
statement
statement

...
}
catch (ExceptionClass exceptionObject)
{
statement
statement
...
}
catch (ExceptionClass exceptionObject)
{
statement
statement
...
}
...

Example:

 
try 
{
System.out.println("What is your name?");
String name = console.readLine();
System.out.println("Hello,"+name +"!");
}
catch (IOException exception)
{
exception.printStackTrace();
System.exit(1);
}

Purpose:

To execute one or more statements that may generate exceptions. If an exception of a particular type occurs, then stop executing those statements and instead go to the matching catch clause. If no exception occurs, then skip the catch clauses.

The finally Clause

The finally Clause

BufferedReader in = null; 
try
{
in = new BufferedReader(
new FileReader(filename));
purse.read(in);
}
finally
{
if (in !=null) in.close();
}

The finally Clause

Syntax 14.4: The finally Clause

  try
{
   statement
   statement

   ...
}
finally
{
   statement
   statement

   ...
}

Example:

 
BufferedReader in = null; 
try
{
in = new BufferedReader(
new FileReader(filename));
purse.read(in);
}
finally
{
if (in !=null) in.close();
}

Purpose:

To execute one or more statements that may generate exceptions, and to execute the statements in the finally clause whether or not an exception occured. 

A Complete Example

The read method of the Coin class

public boolean read(BufferedReader in) throws IOException 
{
String input =in.readLine();
if (input == null) // normal end of file
return false;
value = Double.parseDouble(input);
// may throw unchecked NumberFormatException
name = in.readLine();
if (name == null) // unexpected end of file
throw new EOFException("Coin name expected");
return true;
}

The read method of the Purse class

public void read(BufferedReader in) 
throws IOException
{
boolean done = false;
while (!done)
{
Coin c = new Coin();
if (c.read(in)) add(c);
else done =true;
}
}

The readFile method of the Purse class

public void readFile(String filename) 
throws IOException
{
BufferedReader in = null;
try
{
in = new BufferedReader(
new FileReader(filename));
read(in);
}
finally
{
if (in != null)
in.close();
}
}

User interaction in main

boolean done = false; 
String filename = JOptionPane.showInputDialog("Enter file name");
while (!done)
{
try
{
Purse myPurse = new Purse();
myPurse.readFile(filename);
System.out.println("total=" + myPurse.getTotal());
done =true;
}
catch (IOException exception)
{
System.out.println("Input/output error " + exception);
}
catch (NumberFormatException exception)
{
exception.printStackTrace(); // error in file format
}
if (!done)
{
filename = JOptionPane.showInputDialog( "Try another file:");
if (filename == null)
done =true;
}
}

Scenario

  1.  PurseTest.main calls Purse.readFile
  2. Purse.readFile calls Purse.read
  3. Purse.read calls Coin.read
  4. Coin.read throws an EOFException
  5. Coin.read has no handler for the exception and terminates immediately. 
  6. Purse.read has no handler for the exception and terminates immediately
  7. Purse.readFile has no handler for the exception and terminates immediately after executing the finally clause and closing the file. 
  8. PurseTest.main has a handler for an IOException , a superclass of EOFException. That handler prints a message to the user. Afterwards, the user is given another chance to enter a file name. Note that the statement printing the purse total has been skipped.

File PurseTest.java

1import javax.swing.JOptionPane;
2import java.io.IOException;
3
4/**
5   This program prompts the user to enter a file name
6   with coin values. A purse object is filled with
7   the coins specified in the file. In case of an exception,
8   the user can choose another file.
9*/
10public class PurseTest
11{
12   public static void main(String[] args)
13   {
14      boolean done = false;
15      String filename 
16         = JOptionPane.showInputDialog("Enter file name");
17
18      while (!done)
19      {
20         try
21         {
22            Purse myPurse = new Purse();
23            myPurse.readFile(filename);
24            System.out.println("total=" + myPurse.getTotal());
25            done = true;
26         }   
27         catch (IOException exception)        
28         {
29            System.out.println("Input/output error " + exception);  
30         }   
31         catch (NumberFormatException exception)
32         {         
33            exception.printStackTrace();
34         }
35
36         if (!done)
37         {
38            filename = JOptionPane.showInputDialog(
39               "Try another file:");
40            if (filename == null) done = true;
41         }
42      }
43      System.exit(0);
44   }
45}

File Purse.java

1import java.io.BufferedReader;
2import java.io.FileReader;
3import java.io.IOException;
4
5/**
6   A purse computes the total of a collection of coins.
7*/
8public class Purse
9{
10   /**
11      Constructs an empty purse.
12   */
13   public Purse()
14   {
15      total = 0;
16   }
17
18   /**
19      Read a file with coin descriptions and adds the coins
20      to the purse.
21      @param filename the name of the file
22   */
23   public void readFile(String filename)
24      throws IOException
25   {
26      BufferedReader in = null;
27      try
28      {  
29         in = new BufferedReader(new FileReader(filename));
30         read(in);
31      }
32      finally
33      {
34         if (in != null) in.close();
35      }
36   }
37
38   /**
39      Read a file with coin descriptions and adds the coins
40      to the purse.
41      @param in the buffered reader for reading the input
42   */
43   public void read(BufferedReader in) 
44      throws IOException
45   {  
46      boolean done = false;
47      while (!done)
48      {
49         Coin c = new Coin();
50         if (c.read(in))
51            add(c);
52         else
53            done = true;
54      }
55   }
56
57   /**
58      Add a coin to the purse.
59      @param aCoin the coin to add
60   */
61   public void add(Coin aCoin)
62   {
63      total = total + aCoin.getValue();
64   }
65
66   /**
67      Get the total value of the coins in the purse.
68      @return the sum of all coin values
69   */
70   public double getTotal()
71   {
72      return total;
73   }
74
75   private double total;
76}
77

File Coin.java

1import java.io.BufferedReader;
2import java.io.EOFException;
3import java.io.IOException;
4
5/**
6   A coin with a monetary value.
7*/
8public class Coin
9{
10   /**
11      Constructs a default coin.
12      Use the read method to fill in the value and name.
13   */
14   public Coin()
15   {
16      value = 0;
17      name = "";
18   }
19
20   /**
21      Constructs a coin.
22      @param aValue the monetary value of the coin.
23      @param aName the name of the coin
24   */
25   public Coin(double aValue, String aName) 
26   { 
27      value = aValue; 
28      name = aName;
29   }
30
31   /**
32      Reads a coin value and name.
33      @param in the reader
34      @return true if the data was read, 
35      false if the end of the stream was reached
36   */
37   public boolean read(BufferedReader in) 
38      throws IOException
39   {  
40      String input = in.readLine();
41      if (input == null) return false;
42      value = Double.parseDouble(input);
43      name = in.readLine();
44      if (name == null) 
45         throw new EOFException("Coin name expected");
46      return true;
47   }
48
49   /**
50      Gets the coin value.
51      @return the value
52   */
53   public double getValue() 
54   {
55      return value;
56   }
57
58   /**
59      Gets the coin name.
60      @return the name
61   */
62   public String getName() 
63   {
64      return name;
65   }
66
67   private double value;
68   private String name;
69}
70
71
72
73
74
75
76
77
78