In this lesson we'll focus on how to use Java's exception handling mechanisms—both
We'll also introduce a few new wrinkles to round out our understanding of this particular system.
Our focus is on real-word patterns for working with and handling errors.
Before we go on, let's look at a few further wrinkles in Java exception handling that we haven't touched on yet.
First, you may have wondered: what happens if you throw an exception inside a
Let's try it:
You'll notice that the second exception is thrown out of the
Of course, we can rewrap the entire
try-catch in another
Note that exceptions thrown inside a
catch block cannot be caught by the same
try-catch in which they were thrown.
So this doesn't work:
try-catch blocks can include an additional component: a
finally block is always executed, regardless of whether an exception was thrown or not.
Let's see how that works:
If you run this a few times, you'll notice that regardless of whether we complete the
try block successfully or enter the
finally block is always executed.
One of the cool things about
finally is that it is always executed.
Even if the try includes a
This feature of
finally makes it useful when a method needs to do some kind of cleanup before exiting.
We haven't run into this scenario yet, but you will sometimes.
And when you do,
finally will be there for you!
Next let's look at a few common exception handling patterns.
Previously we've presented how to handle bad inputs using
But here's the dirty truth about Java
assertions: they are not on by default!
If you examine the Java command line options you'll see that you need to pass a special flag to
java to turn assertions on.
Let's look at how that works in practice in a brief screencast:
assert is enabled in all of our playgrounds.
However, in other Java environments—such as on Android—it may be hard or impossible to enable assertions.
While they can be useful during testing, the right thing to do in most cases is to throw an
Exception rather than rely on
However, we can replace many of the places where we had previously used
assert with commonly available non-checked Java exceptions.
When checking parameters to a method,
IllegalArgumentException is usually what you want to use:
Note that because
IllegalArgumentException is unchecked, you don't need to use
throws to declare that the method throws it.
And the compiler will not require that you catch it.
This is good, since usually an
IllegalArgumentException indicates that the inputs to a method contradict the documentation.
When designing our Java classes, there are times when we want to enforce patterns of usage that span multiple methods. To make that more concrete, let's look at an example together:
Sometimes our code needs to take a series of steps to complete some action.
If any of those steps fail, the entire operation fails.
This can be a good place to use a
try-catch to avoid having to do a lot of error checking after each step.
Let's look at an example of this:
Sometimes when an error occurs we just want to log that it happened, but then let it continue to propagate. We can do this by rethrowing the error out of the catch block:
You can also use this technique to convert a checked exception to an unchecked exception:
Why would we do this?
In some cases, even if the compiler will insist that we "handle" a checked exception, there really isn't anything reasonable to do other than crash.
In that case, converting the checked exception to an unchecked
IllegalStateException above) simplifies the error handling.
Methods that call our method now don't themselves need to handle the exception, because it is unchecked.
Once you start writing your own libraries and sharing code with others, it can be helpful to design your own custom exceptions.
One reason to do this is that it allows users of your code to better understand what went wrong.
And to do more accurate error handling by establishing multiple
catch blocks that deal with different kinds of exceptions.
Exception could not be easier:
Note that this creates a checked exception.
Usually that's what you want, since there is usually a reasonable unchecked exception already available for you.
But you can create new unchecked exceptions similarly by extending