3.6. Checked vs. Unchecked Exceptions

In Java, exceptions are either checked or unchecked. Checked exceptions must be explicitly caught or propagated by the programmer, whereas unchecked exceptions may or may not be handled by the programmer. In this section, we will see two short programs. One containing code that potentially throws an unchecked exception and another that potentially throws a checked exception.

3.6.1. Unchecked Exceptions

Unchecked exceptions do not have to be caught. You have likely encountered various unchecked exceptions in the past. If you don’t place code that could throw an unchecked exception into a try-catch statement, the compiler will not generate an error message. However, if there is a problem, you will see it at runtime when the program crashes.

Test Yourself

Take a moment to carefully read through the code below. Do you see where the exception object will be created and thrown? Write what you expect to happen in your notes.

1package exceptions;
2
3public class Unchecked {
4   public static void main(String [] args) {
5      int result = 4/0;
6      System.out.println(result);
7   } // main
8} // Test

If you said that an exception object would be created on line 5, you are correct. Specifically, there is a problem when the program attempts to divide by zero.

Extra Practice: Compiling the Code on Odin

If you would like to practice compiling code to a named package, try compiling the example above on Odin.

If you get stuck during the compilation process, the short video below demonstrates how to properly compile and run this code:

When the program is run, you get an error message similar to the following:

Exception in thread "main" java.lang.ArithmeticException: / by zero
   at exceptions.Unchecked.main(Unchecked.java:5)

An ArithmeticException (specifically, dividing by zero) caused our program to crash. Since ArithmeticException is an unchecked exception, the Java compiler did not force us (the programmer) to catch or propagate this exception. It is completely up to the programmer to decide whether or not to handle exceptions of this type. Since we didn’t handle it, our program crashed. The compiler allowed us to compile our code despite the fact that we were at risk of the program crashing at runtime.

In your previous class, you like encountered output similar to the above due to other unchecked exceptions such as: StringIndexOutOfBoundsException, NullPointerException, NumberFormatException, etc.

3.6.2. Checked Exceptions

Checked exceptions must either be caught or explicitly propagated to the calling method. If you don’t place code that could throw a checked exception into a try-catch statement or add a throws clause to the method signature, you will get an error message at compile time.

Lets see how the compiler behaves when we have a block of code that may generate a checked exception:

Code Example

Take a moment to read through the code below. Some parts may be unfamiliar to you, but try to understand what it is doing at a high level. Note that the Scanner object is created using a File instead of System.in. That just means that the Scanner will read from a file instead of standard input. The methods available on the Scanner object work as you would expect.

Write down any thoughts/guesses you have related to where an exception object could potentially be thrown in this code.

 1package exceptions;
 2
 3import java.util.Scanner;
 4import java.io.File;
 5
 6public class Checked {
 7    public static void main (String[] args) {
 8        File notesFile = new File("notes.txt");
 9        Scanner input = new Scanner(notesFile);
10        System.out.println(input.nextLine());
11    } // main
12} // Checked

In the program above, we are reading the first line of the file notes.txt. The first line of the main method creates a File object which is referred to by the notesFile variable. Then, it passes this object reference to the Scanner constructor. The input object will read its input from the file (not the keyboard). Note: the notes.txt file does not currently exist - so that’s where we might run into problems! We will create the notes.txt file in a later step.

Compiling the Code on Odin

Test Yourself

Attempt to compile Checked.java on Odin. If you execute the correct commands, you should get an error similar to the following:

src/exceptions/Checked.java:9: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
   Scanner input = new Scanner(notesFile);
                   ^
Test Yourself Solution (Try compiling the code before opening)

The short video below demonstrates one way to compile the Checked.java file and generate the expected error message:

Make a mental note of this error message. It is a common one in Java programming.

The error message is telling us that the Scanner constructor throws a FileNotFoundException, which is a checked exception. In fact, this error message alone is enough to inform us that the we need to deal with a checked exception on the indicated line.

Two Options to Address a Checked Exception:

  1. surround the relevant code with a try-catch; or

  2. add a throws clause to the enclosing method (i.e., the method containing the call) to propagate this exception if it occurs.

In Checked.java, the enclosing method is main. If we were to choose option #2, we would be telling Java to propagate the exception out of main which would lead to a crash. We never want to add a throws clause to the main method as there is no code in our program above the main method to handle the exception.

To fix Checked.java, we should use the first approach.

Test Yourself

Take a few minutes to see if you can add an appropriate try-catch statement to Checked.java and get the code to compile.

Hint: You will need to import java.io.FileNotFoundException since it is not in the java.lang package.

Test Yourself Solution (Don’t answer until answering the question)

Here is one version of the Checked.java file that will compile:

package exceptions;

import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;

public class Checked {
    public static void main (String[] args) {
        File notesFile = new File("notes.txt");
        Scanner input = null;
        try {
            input = new Scanner(notesFile);
        } catch (FileNotFoundException e) {
            System.out.println("notes.txt cannot be found");
        } // try
        System.out.println(input.nextLine());
    } // main
} // Checked

Go ahead and run the program. If you haven’t created the notes.txt file, you should see the message from the catch statement.

Now, try creating a notes.txt file and running the program again.

Important Note: The notes.txt file should be in the directory where you run the java command to run the program. If you run the program from the parent directory of bin and src, that’s where the file should be. It should also contain at least one line of text.

Execute exceptions.Checked. It should print the first line of notes.txt!

3.6.3. Identifying Checked vs. Unchecked Exceptions

One way to check if an exception is checked or unchecked is to try and compile the code. However, there is an even better way to check by looking at the Java API.

  1. Visit the Java API page for ArithmeticException.

  2. At the top of the page, there is a hierarchy of Java classes which looks like this:

    ArithmeticException Unchecked Example

    You can tell that ArithmeticException is an unchecked exception because java.lang.RuntimeException is listed in the hierarchy. If you cannot find java.lang.RuntimeException in the hierarchy for a given exception, then that tells you it is a checked exception.

  3. For an example of a checked exception, see FileNotFoundException. You should notice that java.lang.RuntimException is not found in the hierarchy indicating that it is a checked exception.

Rapid Fire Review
  1. What type of exception must be explicitly caught or propagated by the programmer in Java?

    1. checked exception

    2. unchecked exception

    3. runtime exception

    4. syntax exception

  2. What happens if you try to compile a Java program that includes code which might throw a checked exception without handling it?

    1. The compiler ignores the exception

    2. The program crashes at runtime

    3. The compiler generates an error message

    4. The exception is automatically caught

  3. How can you tell if an exception is checked or unchecked by looking at the Java API?

    1. If the exception is a subclass of java.lang.Exception, it is unchecked

    2. If the exception is a subclass of java.lang.RuntimeException, it is unchecked

    3. If the exception is listed in the java.lang package, it is checked

    4. If the exception is a subclass of java.lang.Error, it is checked

    5. If the exception is a subclass of java.lang.RuntimeException, it is checked