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
Erroras their parent (or grandparent, etc) class. - All exceptions have the class
Exceptionas their parent (or grandparent, etc) class. - The parent class of both
ErrorandExceptionisThrowable.
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
RuntimeExceptiondon’t have to be declared. - All other exceptions that may be thrown have to be declared using the keyword
throwsin 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, andfinallyto 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
tryblocks that should really be written as a single largetryblock because the statements inside the many smalltryblocks 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); } }