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:
surround the relevant code with a try-catch; or
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.
Visit the Java API page for ArithmeticException.
At the top of the page, there is a hierarchy of Java classes which looks like this:
You can tell that
ArithmeticException
is an unchecked exception becausejava.lang.RuntimeException
is listed in the hierarchy. If you cannot findjava.lang.RuntimeException
in the hierarchy for a given exception, then that tells you it is a checked exception.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
What type of exception must be explicitly caught or propagated by the programmer in Java?
checked exception
unchecked exception
runtime exception
syntax exception
What happens if you try to compile a Java program that includes code which might throw a checked exception without handling it?
The compiler ignores the exception
The program crashes at runtime
The compiler generates an error message
The exception is automatically caught
How can you tell if an exception is checked or unchecked by looking at the Java API?
If the exception is a subclass of java.lang.Exception, it is unchecked
If the exception is a subclass of java.lang.RuntimeException, it is unchecked
If the exception is listed in the java.lang package, it is checked
If the exception is a subclass of java.lang.Error, it is checked
If the exception is a subclass of java.lang.RuntimeException, it is checked