Exception Handling
Introduction
• Errors can be dealt with at place error occurs
– Easy to see if proper error checking implemented
– Harder to read application itself and see how code works
• Exception handling
– Makes clear, robust, fault-tolerant programs
– Java removes error handling code from "main line" of program
• Common failures
– Memory exhaustion
– Out of bounds array subscript
– Division by zero
– Invalid method parameters
Introduction
• Exception handling
– Catch errors before they occur
– Deals with synchronous errors (i.e., divide by zero)
– Does not deal with asynchronous errors
• Disk I/O completions, mouse clicks - use interrupt processing
– Used when system can recover from error
• Exception handler - recovery procedure
• Error dealt with in different place than where it occurred
– Useful when program cannot recover but must shut down
cleanly
Introduction
• Exception handling
– Should not be used for program control
• Not optimized, can harm program performance
– Improves fault-tolerance
• Easier to write error-processing code
• Specify what type of exceptions are to be caught
– Another way to return control from a function or block of
code
When Exception Handling Should
Be Used
• Error handling used for
– Processing exceptional situations
– Processing exceptions for components that cannot handle
them directly
– Processing exceptions for widely used components
(libraries, classes, methods) that should not process their
own exceptions
– Large projects that require uniform error processing
The Basics of Java Exception Handling
• Exception handling
– Method detects error which it cannot deal with
• Throws an exception
– Exception handler
• Code to catch exception and handle it
– Exception only caught if handler exists
• If exception not caught, block terminates
The Basics of Java Exception Handling
• Format
– Enclose code that may have an error in try block
– Follow with one or more catch blocks
• Each catch block has an exception handler
– If exception occurs and matches parameter in catch block
• Code in catch block executed
– If no exception thrown
• Exception handling code skipped
• Control resumes after catch blocks
try{
code that may throw exceptions
}
catch (ExceptionType ref) {
exception handling code
}
The Basics of Java Exception Handling
• Termination model of exception handling
– throw point
• Place where exception occurred
• Control cannot return to throw point
– Block which threw exception expires
– Possible to give information to exception handler
An Exception Handling Example: Divide by
Zero
• Example program
– User enters two integers to be divided
– We want to catch division by zero errors
– Exceptions
• Objects derived from class Exception
– Look in Exception classes in java.lang
• Nothing appropriate for divide by zero
• Closest is ArithmeticException
• Extend and create our own exception class
An Exception Handling Example: Divide by
Zero
5 public class DivideByZeroException
6 extends ArithmeticException {
7 public DivideByZeroException()
12 public DivideByZeroException( String message )
– Two constructors for most exception classes
• One with no arguments (default), with default message
• One that receives exception message
• Call to superclass constructor
– Code that may throw exception in try block
– Error handling code in catch block
– If no exception thrown, catch blocks skipped
1 // Fig. 14.1: DivideByZeroException.java
2 // Definition of class DivideByZeroException.
3 // Used to throw an exception when a
4 // divide-by-zero is attempted.
1. Class DivideByZero
5 public class DivideByZeroException Define our own Exception
exception class
(extends
6 extends ArithmeticException { (exceptions are thrown objects).
Arithmetic
7 public DivideByZeroException()
Exception)
Default constructor (default message)
8 {
and customizable message
9 super( "Attempted to divide by zero" );
constructor. 1.2 Constructors
10 }
11
12 public DivideByZeroException( String message ) 1.3 super
13 {
14 super( message );
15 }
16 }
17
18 // Fig. 14.1: DivideByZeroTest.java
19 // A simple exception handling example.
20 // Checking for a divide-by-zero-error.
21 import java.text.DecimalFormat;
22 import javax.swing.*; 1. Set up GUI
23 import java.awt.*;
24 import java.awt.event.*;
25
26 public class DivideByZeroTest extends JFrame
27 implements ActionListener {
28 private JTextField input1, input2, output;
29 private int number1, number2;
30 private double result;
31
32 // Initialization
33 public DivideByZeroTest()
34 {
35 super( "Demonstrating Exceptions" );
36
37 Container c = getContentPane();
38 c.setLayout( new GridLayout( 3, 2 ) );
39
40 c.add( new JLabel( "Enter numerator ",
41 SwingConstants.RIGHT ) );
42 input1 = new JTextField( 10 );
43 c.add( input1 );
44
45 c.add(
46 new JLabel( "Enter denominator and press Enter ",
47 SwingConstants.RIGHT ) );
48 input2 = new JTextField( 10 );
49 c.add( input2 );
50 input2.addActionListener( this );
51
52 2. Process GUI events
53
54 c.add( new JLabel( "RESULT ", SwingConstants.RIGHT ) );
2.1 try block
55 output = new JTextField();
56 c.add( output );
57
58 setSize( 425, 100 );
59 show();
60 }
61
62 // Process GUI events Notice enclosing try block. If an exception is
63 public void actionPerformed( ActionEvent e )
thrown in the block (even from a method call),
64 {
the entire block is terminated.
65 DecimalFormat precision3 = new DecimalFormat( "0.000" );
66
67 output.setText( "" ); // empty the output JTextField
68
69 try {
70 number1 = Integer.parseInt( input1.getText() );
71 number2 = Integer.parseInt( input2.getText() );
72
73 result = quotient( number1, number2 );
74 output.setText( precision3.format( result ) );
75 }
76 catch ( NumberFormatException nfe ) { catch blocks have error handling
77 JOptionPane.showMessageDialog( this, code. Control resumes after the
78 "You must enter two integers", catch blocks.
79 "Invalid Number Format",
80 JOptionPane.ERROR_MESSAGE ); The first block
2.2makes
catchsure the
blocks
81 } inputs are of the correct type.
82 catch ( DivideByZeroException dbze ) {
83 JOptionPane.showMessageDialog( this, dbze.toString(), 3. quotient
84 "Attempted to Divide by Zero",
85 JOptionPane.ERROR_MESSAGE );
86 }
4. main
87 }
88
89 // Definition of method quotient. Used to demonstrate
90 // throwing an exception when a divide-by-zero error
91 // is encountered.
92 public double quotient( int numerator, int denominator )
93 throws DivideByZeroException
94 {
95 if ( denominator == 0 ) Method quotient throws an
96 throw new DivideByZeroException(); DivideByZeroException
97
exception (object) if
98 return ( double ) numerator / denominator;
99 }
denominator == 0.
100
101 public static void main( String args[] )
102 {
103 DivideByZeroTest app = new DivideByZeroTest();
104
105
106 app.addWindowListener(
107 new WindowAdapter() {
108 public void windowClosing( WindowEvent e )
109 {
110 e.getWindow().dispose();
111 System.exit( 0 );
112 }
113 }
114 );
115 }
116 }
Program Output
Program Output
Try Blocks
• Exceptions that occurs in a try block
– Usually caught by handler specified by following catch
block
try{
code that may throw exceptions
}
catch ( ExceptionType ref ) {
exception handling code
}
• Can have any number of catch blocks
– If no exceptions thrown, catch blocks skipped
Throwing an Exception
• throw
– Indicates exception has occurred (throwing an exception)
– Operand
• Object of any class derived from Throwable
95 if ( denominator == 0 )
96 throw new DivideByZeroException();
– Derived from Throwable:
• Exception - most programmers deal with
• Error - serious, should not be caught
• When exception thrown
– Control exits current try block
– Proceeds to catch handler (if exists)
Throwing an Exception
• Exceptions
– Can still throw exceptions without explicit throw statement
• ArrayIndexOutOfBoundsException
– Terminates block that threw exception
Catching an Exception
• catch blocks
– Contain exception handlers
– Format:
catch( ExceptionType ref ) {
error handling code
}
82 catch ( DivideByZeroException dbze ) {
83 JOptionPane.showMessageDialog( this,
dbze.toString(),
84 "Attempted to Divide by Zero",
85 JOptionPane.ERROR_MESSAGE );
86 }
– To catch all exceptions, catch an exception object:
catch( Exception e )
Catching an Exception
• Catching exceptions
– First handler to catch exception does
• All other handlers skipped
– If exception not caught
• Searches enclosing try blocks for appropriate handler
try{
try{
throw Exception2
}
catch ( Exception1 ){...}
}
catch( Exception2 ){...}
– If still not caught, applications terminate
Catching an Exception
• Information
– Information can be passed in the thrown object
• If a catch block throws an exception
– Exception must be processed in the outer try block
• Usage of exception handlers
– Rethrow exception (next section)
• Convert exception to different type
– Perform recovery and resume execution
– Look at situation, fix error, and call method that generated
exception
– Return a status variable to environment
Rethrowing an Exception
• Rethrowing exceptions
– Use if catch handler cannot process exception
– Rethrow exception with the statement:
throw e;
• Detected by next enclosing try block
– Handler can always rethrow exception, even if it performed
some processing
Throws Clause
• Throws clause
– Lists exceptions that can be thrown by a method
int g( float h ) throws a, b, c
{
// method body
}
92 public double quotient( int numerator, int denominator )
93 throws DivideByZeroException
– Method can throw listed exceptions
Throws Clause
• Run-time exceptions
– Derive from RunTimeException
– Some exceptions can occur at any point
• ArrayIndexOutOfBoundsException
• NullPointerException
– Create object reference without attaching object to
reference
• ClassCastException
– Invalid casts
– Most avoidable by writing proper code
Throws Clause
• Checked exceptions
– Must be listed in throws clause of method
– All non-RuntimeExceptions
• Unchecked exceptions
– Can be thrown from almost any method
• Tedious to write throws clause every time
• No throws clause needed
– Errors and RunTimeExceptions
Throws Clause
• Catch-or-declare requirement
– If method calls another method that explicitly throws
checked exceptions
• Exceptions must be in original method's throws clause
– Otherwise, original method must catch exception
– Method must either catch exception or declare it in the
throws clause
Exceptions and Inheritance
• Inheritance
– Exception classes can have a common superclass
– catch ( Superclass ref )
• Catches subclasses
• "Is a" relationship
– To catch all exceptions, catch an exception object:
catch( Exception e )
– Polymorphic processing
– Easier to catch superclass than catching every subclass
finally Block
• Resource leaks
– Programs obtain and do not return resources
– Automatic garbage collection avoids most memory leaks
• Other leaks can still occur
• finally block
– Placed after last catch block
– Can be used to returns resources allocated in try block
– Always executed, irregardless whether exceptions thrown or
caught
– If exception thrown in finally block, processed by
enclosing try block
1 // Fig. 14.9: UsingExceptions.java
2 // Demonstration of stack unwinding.
3 public class UsingExceptions {
4 public static void main( String args[] )
5 { 1. main
6 try { Call method throwException
7 throwException(); (enclosed in a try block).
8 } 1.1 throwException
9 catch ( Exception e ) {
10 System.err.println( "Exception handled in Throw Exception.
main"an); The catch block
1.2 catch
11 } cannot handle it, but the finally block
12 } executes irregardless.
13 2. Define
14 public static void throwException() throws Exception throwException
15 {
16 // Throw an exception and catch it in main.
17 try { 2.1 try
18 System.out.println( "Method throwException" );
19 throw new Exception(); // generate exception
20 }
2.2 catch
21 catch( RuntimeException e ) { // nothing caught here
22 System.err.println( "Exception handled in " + 2.3 finally
23 "method throwException" );
24 }
25 finally {
26 System.err.println( "Finally is always executed" );
27 }
28 }
29 }
Method throwException
Finally is always executed
Exception handled in main Program Output
Using printStackTrace and
getMessage
• Class Throwable
– Superclass of all exceptions
– Offers method printStackTrace
• Prints method call stack for caught Exception object
– Most recent method on top of stack
• Helpful for testing/debugging
– Constructors
• Exception()
• Exception( String informationString )
– informationString may be accessed with method
getMessage
1 // Fig. 14.10: UsingExceptions.java
2 // Demonstrating the getMessage and printStackTrace
3 // methods inherited into all exception classes.
4 public class UsingExceptions {
5 public static void main( String args[] )
6 {
1. main
Call method1, which calls
7 try { method2, which calls method3,
8 method1(); 1.1 try
which throws an exception.
9 }
10 catch ( Exception e ) {
11 System.err.println( e.getMessage() + "\n" ); 1.2 getMessage
12
13 e.printStackTrace();
14 }
getMessage prints the 1.3
String the
printStackTrace
15 } Exception was initialized with.
16
17 public static void method1() throws Exception 2. method1
18 {
19 method2(); printStackTrace prints the methods in this
20 } order: 3. method2
21
22
method3
public static void method2() throws Exception
method2 4. method3
23 {
24 method3(); method1
25 } main 4.1 throw
26
27 public static void method3() throws (order they were called
Exception when exception occurred)
28 {
29 throw new Exception( "Exception thrown in method3" );
30 }
31 }
Exception thrown in method3
java.lang.Exception: Exception thrown in method3
at UsingExceptions.method3(UsingExceptions.java:28)
at UsingExceptions.method2(UsingExceptions.java:23)
Program Output
at UsingExceptions.method1(UsingExceptions.java:18)
at UsingExceptions.main(UsingExceptions.java:8)