Exception Handling in Java
Working With Exceptions
When working with exceptions, you will either throw them or handle them. Exceptions are thrown when something isn't what it is expected to be. For example, trying to read a file that doesn't exist. When you are executing code that can throw an exception, you can wrap that code in a try block to execute code if a specific exception occurs.
Throwing Exceptions
Exceptions are thrown using a throw statement. Depending on if you are throwing a checked exception or an unchecked exception will change how it is written.
Throwing Unchecked Exceptions
Unchecked exceptions are the easiest to throw. You simply provide a throw statement followed by the exception instance you are throwing.
public void method() {
throw new UncheckedException();
}
Throwing Checked Exceptions
Throwing a checked exception is written the same as an unchecked exception. The difference between the two is that checked exceptions need to be added to a method signatures throws clause.
public void method() throws CheckedException {
throw new CheckedException();
}
When you have to specify the checked exceptions in a throws clause, you are generally going to want to list the individual subclasses instead of being too generic and using a superclass.
Try Blocks
When you are executing a method that can throw an exception and you want to handle it, you execute that method in a try block. Try blocks must have a catch block and/or a finally block. This section only shows the try block, which is not valid syntax.
// Partial try block.
try {
methodThatCanThrowException();
}
// ...
When a method throws an exception, you do not have to handle that exception when the method is invoked. It can be handled anywhere in the call stack.
public void method1() {
// Partial try block.
try {
method2();
}
// ...
}
public void method2() {
method3();
}
public void method3() {
throw new RuntimeException();
}
Catch Blocks
You can provide a block of code to execute when an exception is thrown by a method. This is called a catch block, and it is written after a try block. Catch blocks will execute based on the exception in the catch block. For example:
public void method() {
throw new RuntimeException();
}
try {
method();
} catch (final RuntimeException e) {
// ...
}
If method() throws a RuntimeException, the block of code executes in the catch block. When specifying a superclass in a catch block, all subclasses of that superclass will be caught in that catch block.
Multiple Catch Blocks
You can have multiple catch blocks. This allows you to execute a different code block depending on the exception that is thrown.
try {
// ...
} catch (final IOException e) {
// ...
} catch (final RuntimeException e) {
// ...
} catch (final Exception e) {
// ...
}
Union Catch Blocks
Catch blocks also support union catch blocks. You can specify multiple exceptions in a union catch block. If any of the exceptions match, that catch block will execute.
try {
// ...
} catch (final IOException | RuntimeException e) {
// ...
}
Finally Blocks
A finally block is a block of code that is written after the catch block(s). A finally block is guaranteed to execute after the try and catch blocks, regardless of whether there was an exception thrown or not. Finally blocks are a good way to clean up resources. When a try block contains a finally block, catch blocks are optional. For example:
try {
methodThatCanThrowException();
} finally {
// ...
}
If an exception is thrown, it will execute the finally block and then throw the exception.
try {
methodThatCanThrowException();
} catch (final Exception e) {
// ...
} finally {
// ...
}
If an exception is thrown in the try block, this will execute the catch block first and then the finally block.
Return Statements
Return statements should never be in a finally block. If an exception is thrown and a finally block has a return statement, that exception will be dropped like it was never thrown.
Throw Statements
Throw statements shouldn't be used in a finally block. If a throw statement is in a finally block, it will throw that exception instead of the original exception that was thrown.
Conclusion
Exceptions are caught and handled in try blocks that contain a catch block. Try blocks must have either a catch block or a finally block or both. When using finally blocks, do not use return statements or throw statements.