Exceptions in Java are something that can be quite mysterious when you first learn the language, but they are actually quite simple. If you are new to Java, or are still in the phase where you try-catch when your IDE says so without really understanding why, then read on.
The throws keyword
If you have written Java code, you are probably familiar with try and catch blocks. However I am going to start this guide with the keyword throws as I think it is often misunderstood by beginners, and along with the other keyword throw gives us an idea of where exceptions come from.
The throws keyword tells the compiler that this method may throw an exception. It is important to understand that this doesn’t mean that it will throw an exception, just that it may.
Throws comes after the method signature, such as:
If your code could throw an exception then you can either catch it, or declare that the method may throw it using the throws keyword. However, it is bad practice generally to just throw the Exception back up to the method that called this one, you would normally want to catch the exception unless you are throwing it yourself with the throw keyword.
The throw keyword
The (singular) throw keyword specifically throws an Exception. If you have used libraries that throw checked exceptions such as database drivers, then this is what happens inside the library. A pseudo code example of this is below:
This is just an example to demonstrate what happens inside some of the libraries you might have used, if the thrown exception is of the type checked exception (which we will come to shortly) then you will have to catch or declare this exception if you call this method (as you do when you do a database query).
I imagine if you’ve written a few Java programs, you have come across the try/catch block. If an exception is thrown, you can either throw it up to the calling method using throws (rarely a good idea unless you know for sure how it is going to be handled) or you can catch it and deal with it.
If a method declares that it throws a checked exception then the Java compiler (and your IDE) will require any method that calls that method to handle the exception. In most cases you will want to catch the exception and perform some actions, perhaps print a log or close any objects to release external resources.
This is a somewhat classic example that may be familiar to you. If there is no exception then the code in the try block is run, then the code in the finally block is run (the finally block is optional).
If there is an exception then the code in the try block stops immediately and the code in the finally block is run , then the code in the catch block (if the Exception type is the same or a subclass of the one being caught). Keep in mind that the finally runs before the catch block.
You can also have a try and finally without a catch, which allows you to do things like run code after you return something from a method, but that is somewhat irrelevant here.
Checked and Unchecked Exceptions
A further piece to the puzzle is that there are two main types of exceptions. These are checked and unchecked exceptions. The main difference is that checked exceptions have to be either caught or declared using throws, whereas with unchecked exceptions this is optional.
Unchecked exceptions are for things that you can’t predict, things that should never happen if the code is working as it should. These are things like NullPointerException, ArrayOutOfBoundsExceptions, FileNotFoundException and other I/O exceptions, or incorrectly used math functions. With these unchecked exceptions you can still declare them with throws, throw them with throw, or catch them in a catch block, but all of this is optional. These exceptions are not checked at compile time (hence the name) and do not require you to declare or catch them. This is because you would never intentionally throw one of these, it is a sign that something has gone seriously wrong, of course you can still catch them but generally you would want the program to fail instead and then you fix the bug.
Checked exceptions are for expected but exceptional (for want of a better word) circumstances. These are for things that are out of your control, but could theoretically happen. Things such as a database connection failing (your internet might be down). These are things that may happen and therefore you will probably want your program to be able to respond to them, this is what the catch and finally blocks are for. If you are writing a library you are more likely to create your own Checked exceptions to let users know that something has gone wrong.
How you handle errors is a big subject, with many schools of thought. Some methods have equally valid success and failure outcomes that don’t require an exception, they could simply return true or false. It also depends on the environment you are writing code in as exceptions are part of an object’s interface and have further ramifications in a design-by-contract environment.
Armed with the basics you are in a position to begin thinking about how your application should handle errors, and you know what tools are at your disposal.