Exceptions in Java
Explains how to declare, throw, and catch exceptions in a Java program.
Prerequisites
- Understand Java primitive types
- Understand execution flow and the following Java control structures:
- Sequence
- Selection (if and switch statements)
- Repetition (while, for, and do while statements)
- Understand Java classes, objects, and inheritance.
Objectives
- Distinguish between Java Errors and Exceptions
- Declare that a method might throw an exception
- Throw exceptions
- Correctly handle exceptions using
try
,catch
, andfinally
Errors and Exceptions
- Java has two categories of “bad things” that may happen while a program is running: errors and exceptions.
- An error is a “bad thing” that your Java program cannot do anything to correct, for example:
LinkageError
,VirtualMachineError
,ThreadDeath
. - An exception is a “unexpected thing” or “bad thing” that your Java program may be able to correct, fo/example:
FileNotFoundException
,NumberFormatException
,SecurityException
. - Within a Java program an error or exception is really just an object.
- All errors have the class
Error
as their parent (or grandparent, etc) class. - All exceptions have the class
Exception
as their parent (or grandparent, etc) class. - The parent class of both
Error
andException
isThrowable
.
Partial List of Errors and Exceptions in java.lang and java.io
|
||||
△ | ||||
└──── |
|
|||
△ | ||||
├───── |
|
|||
| | △ | |||
| | ├────── |
| ||
| | ├────── |
| ||
| | ├────── |
| ||
| | ├────── |
| ||
| | └────── |
| ||
| | ||||
└───── |
|
|||
△ | ||||
├───── |
| |||
├───── |
| |||
├───── |
| |||
├───── |
| |||
└───── |
|
1 |
|
|||
△ | ||||
├───────── |
|
|||
├───────── |
|
|||
├───────── |
|
|||
| | △ | |||
| | ├─────────────── |
| ||
| | └─────────────── |
| ||
| | ||||
├───────── |
|
|||
| | △ | |||
| | ├───────────── |
| ||
| | └───────────── |
| ||
| | ||||
├───────── |
|
|||
└───────── |
|
|||
2 |
|
|||
△ | ||||
├───────── |
|
|||
├───────── |
|
|||
└───────── |
|
Declaring that a Method Might Throw an Exception
- Exceptions that extend
RuntimeException
don’t have to be declared. - All other exceptions that may be thrown have to be declared using the keyword
throws
in the header of the method where they might by thrown. - Syntax:
modifiers returnType methodName(param1, param2, …, paramN) throws ExceptionClassName { method body; }
- Example:
public static void checkFile(String filename) throws FileNotFoundException { … }
Throwing an Exception
- To throw an exception do the following:
- Write an if statement to detect the "bad thing".
- Use the keyword throw.
- Create an object of the correct Exception type.
- Syntax:
if (check_for_bad_thing) { throw new ExceptionClassName(); }
- Examples:
public static void checkFile(String filename) throws FileNotFoundException { File file = new File(filename); if (!file.exists()) { throw new FileNotFoundException(filename); } … }
public static void sort(float[] a, int fromIndex, int toIndex) /* This method header has no throws clause because it may throw * ArrayIndexOutOfBoundsException and IllegalArgumentException, * which both inherit from RuntimeException. Exceptions that * inherit from RuntimeException don't have to be declared in * the method header like other exceptions have to be. */ { if (fromIndex < 0) { throw new ArrayIndexOutOfBoundsException(fromIndex); } if (toIndex < 0) { throw new ArrayIndexOutOfBoundsException(toIndex); } if (fromIndex > toIndex) { throw new IllegalArgumentException( "fromIndex (" + fromIndex + ") must be less than or equal to toIndex (" + toIndex + ")"); } … }
Handling an Exception
- Use the Java keywords
try
,catch
, andfinally
to handle exceptions. - Syntax, questions, and answers:
try { /* Which statements belong inside a try block? * Code that is executed in normal circumstances * a) Statements that might cause an exception to be thrown * b) Statements that depend on any statements in group a) */ } catch (ExceptionClassName objectName) { /* What is the purpose of a catch block? * To handle an exception or inform a user about * the exception. */ /* Which statements belong inside a catch block? * Code that is executed when an exception occurs. */ /* Is the catch block optional? * Yes, if there is a finally block. */ } catch (ExceptionClassName objectName) { /* How many catch blocks are allowed with one try block? * Many */ /* If a try block has more than one catch block, how do * we know which exception to list first? * The most specific exception (bottom of the inheritance * hierarchy) must be listed first. The most general * exception (top of the inheritance hierarchy) must be * listed last. */ } finally { /* What is the purpose of a finally block? * To release any resources that were acquired while * executing the try block, for example close files * that were opened in the try block. */ /* Which statements belong inside a finally block? * Code that releases resources that were acquired in * the try block. */ /* When will the code in a finally block be executed? * The JVM guarantees that if any code in a try block is * executed, then the code in its corresponding finally * block will be executed regardless of whether an * exception is thrown or not and caught or not. In other * words, if any code in a try block is executed, the code * in the corresponding finally block will be executed. */ /* Is the finally block optional? * Yes, if there is at least one catch block. */ }
Complete Exception Handling Example
import java.io.*; public class TestExceptions { public static void main(String[] args) { try { double s = addNumbers("numbers.dat"); System.out.println(s); } catch (FileNotFoundException ex) { System.err.println(ex.getMessage()); } catch (IOException ex) { System.err.println(ex.getMessage()); } catch (Exception ex) { System.err.println(ex.getMessage()); } } /* Reads and sums all the double numbers in a file. */ public static double addNumbers(String filename) throws FileNotFoundException, IOException { File file = new File(filename); FileInputStream fin = new FileInputStream(file); DataInputStream din = new DataInputStream(fin); double sum = 0; try { /* This is an infinite loop because .readDouble() * throws an EOFException when it has reached the * end of a file which will terminate the loop. */ while (true) { double d = din.readDouble(); sum += d; } } catch (EOFException e) { /* We have reached the end of the file, which we * expected to happen, so we do nothing here. * When the EOFException is thrown the read loop * above will end. */ } finally { din.close(); } return sum; } }
Common Mistake
- Writing many small
try
blocks that should really be written as a single largetry
block because the statements inside the many smalltry
blocks are dependent on each other.Incorrect
public static void addTwoNumbers() { int a = 0, b = 0; try { String input = JOptionPane.showInputDialog( "Please enter an integer"); a = Integer.parseInt(input); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(null, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } try { String input = JOptionPane.showInputDialog( "Please enter another integer"); b = Integer.parseInt(input); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(null, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } int c = a + b; JOptionPane.showMessageDialog(null, "The sum is " + c); }
Correct
public static void addTwoNumbers() { try { String input = JOptionPane.showInputDialog( "Please enter an integer"); int a = Integer.parseInt(input); input = JOptionPane.showInputDialog( "Please enter another integer"); int b = Integer.parseInt(input); int c = a + b; JOptionPane.showMessageDialog(null, "The sum is " + c); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(null, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } }