CMUQ 15-121 Exceptions



1. Introduction

An exception occurs when Java experiences an error that it doesn’t know how to recover from.

A classic example is divide by 0:

int a = 65 / 0; // This will cause an exception

Another example is trying to access an array outside of its bounds.

int[] arr = new int[20];
arr[25] = 56; // This will cause an exception

2. Types of Exceptions

There are many different types of exceptions, here are a few examples:

Exception Type Description
ArithmeticException An error while performing arithmetic. Most like dividing by 0.
ArrayIndexOutOfBoundsException Trying to access an element of array beyond its size.
FileNotFoundException Trying to open a file that does not exist.
NullPointerException Trying to access an object using a reference that points to null.

Note that there are many more exceptions than this.

3. Checked vs Unchecked Exceptions

For many exceptions, the compiler doesn’t do anything to let you know that they might occur when the program runs. These are called unchecked exceptions (because the compiler doesn’t check for them.) The ArithmeticException, ArrayIndexOutOfBoundsException, and NullPointerException above are unchecked exceptions. If one of these exceptions occurs while your program is running and you’ve haven’t done anything to handle it, then your program just crashes.

For other exceptions, the compiler does check to see if they might possible occur and forces you to write your code in such a way to handle the exception if it does. These are called checked exceptions. If you program uses code that might generate a checked exception, then you are required to handle that exception if it occurs. FileNotFoundException is an example of a checked exception. If you call a method that might cause a FileNotFoundException, your program will not even compile until you have exception handling code in place. We’ll see an example of this in the next section.

4. Handling Exceptions

So how do we handle exceptions and not crash? We write extra code that only runs if the exception occurs. Consider the following file reading example:

import java.io.FileReader;
import java.util.Scanner;

public class FileReadingDemo {
    
    // This code can't run yet, but look at it to understand how to create a scanner from a file.
    public static void main(String args[]) {
                
        FileReader fr = new FileReader("GirlName.txt");
        Scanner inp = new Scanner(fr);
        
        // Read and print out all lines
        while (inp.hasNextLine()) {
            String theLine = inp.nextLine();
            System.out.println(theLine);
        }
    }

}

This code can’t compile because the FileReader constructor contains a checked exception. If the file doesn’t exist, then a FileNotFoundException is thrown, indicating the error. Java requires us to handle this exception, so we need to surround that piece of code with a try-catch statement:

import java.io.FileReader;
import java.util.Scanner;

public class FileReadingDemo {
    
    public static void main(String args[]) {
        FileReader fr;
        
        try {
            fr = new FileReader("GirlName.txt");
            
        } catch(Exception e) {
            System.out.println("Could not open the file!");
            return;
        }
        Scanner inp = new Scanner(fr);
        
        // Read and print out all lines
        while (inp.hasNextLine()) {
            String theLine = inp.nextLine();
            System.out.println(theLine);
        }
        inp.close();
    }

}

Now, if an exception occurs while creating the FileReader then the code after the catch statement will run. It prints an error message and returns. If there is no error, then that code doesn’t run at all.