Skip to content

Errors & Exceptions

Learning Objectives

  • Understand what is meant by an "exception" within an application
  • Understand the distinction between checked and unchecked exceptions
  • Understand how to handle exceptions in Java using the try and catch syntax

Error Handling

When building applications, things can go wrong either at compile time or runtime. It is best practice to handle scenarios where our code does not behave as expected. This is called exception handling.

Thankfully, Java contains syntax for catching and reacting to exceptions:

  • The try statement allows you to define a block of code to be tested for errors while it is being executed.
  • The catch statement allows you to define a block of code to be executed, if an error occurs in the try block.

try {
  //  Block of code to try
}
catch(Exception e) {
  //  Block of code to handle errors
}
A brief explanation of the above code construct - we place our code which we know may potentially throw an exception in the try block; We're trying to run it. If it does end up throwing an exception, this exception is returned to the catch block in the variable which we have defined as parameter e. So, rather than simply breaking the app, we can add business logic to decide what to do next if we so choose. For example, if we are trying to load a file, but we get an exception because the file doesn't actually exist the specified path, we might try to load a file from a different location, or just create a new file and go from there. The point is, it gives you, the programmer, control over the next steps when things go wrong.

Checked and Unchecked Exceptions

In Java, there 2 basic kinds of exceptions: - Checked exceptions: These are forseeable exceptions, such as trying to reading a file that doesn't exist etc. - Unchecked exceptions: These represent errors in application logic, such as reading index 5 in an array that only has 5 elements (index 5 represents the 6th element, which doesn't exist in this example).

Checked Exceptions

Take reading a file as an example of a checked exception - You need to handle this kind of exception at compile time, otherwise your code will not compile for you.

Checked exceptions represent errors outside the control of the program - they can be foreseen, and so they are 'checked for' at compile time. For example, if you are reading a file, Java knows there is a possibility that the file will not exist, and so it requires you to handle a possible FileNotFound exception. Most IDEs, including InjelliJ, highlight these issue for you in realtime (as you program) and suggest solutions, such as either throwing the exception up the call chain to the method that is calling the current one by using the throws keyword (which is like kicking the can down the road. Someone will have to deal with it eventually...), or adding a try/catch block to deal with it directly.

Option 1: Try Catch

Here, we handle a FileNotFound exception directly, using a try catch block:

File file = new File("file.txt");
try {
    FileInputStream stream = new FileInputStream(file);
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

Option 2: Throw it 'Up the Call Chain'

In this example, instead of handling it directly, we use the throws keyword to declare to the method calling this one that it throws an exception of a particular type (in this case, a FileNotFoundException) - this shifts the onus of responsibility onto the calling method. It's a bit like kicking the can down the road; eventually, someone will have to deal with it:

public void readFile() throws FileNotFoundException {
    File file = new File("file.txt");
    FileInputStream stream = new FileInputStream(file);
}

Unchecked Exceptions

If a program throws an unchecked exception, it reflects some error inside the program logic. For example, if we divide a number by 0, Java will throw ArithmeticException:

System.out.println(10 / 0);
You cannot handle this type of exception with a try/catch block, because it is only discovered at runtime. Instead, you must read the terminal output describing the uncaught exception, and correct the defective logic in your code based on the information provided.

Having considered these fundamentals of exception handling, we are ready to take a look at some tasks which involve working with checked exceptions, such as reading and writing files. That will be the subject of our next lesson.

Video Recap