Java Exception Design, what is a Java exception, and how to use Java Exceptions
In this tutorial we are going to learn about Java Exception Design, what Java exception can tell, and how to use Java Exceptions.
Java Exception is a class created to handle abnormal application behavior. In this article, I’ll explain how to use the Java Exception class and how to create your exception structure considering the existing Java Exceptions design. Java exception notion is one of the critical milestones in java and every developer must know it.
Java Exceptions have a structure that is pretty informative and can tell the developer a set of important things (if the developer uses this structure properly). So, here, you can see the basic structure:
The main parent that can catch all possible situations is Throwable which has 2 children: Error and Exception.
Java Error case stands for abnormal situations. Once an Error appears application will be likely shut down.
Java Exceptions, unlike Error, have a chance to recover an application from a problem and try to keep the application up. Exceptions also split into 2 groups:
Exceptions are represented by Runtime and Not Runtime exceptions, also known as checked exceptions. This classification is pretty similar to Error Exceptions but, in that division, the Checked exception is more optimistic in terms of recovery.
In Java, there are 2 types of exceptions. Checked exceptions force developers to create handler exceptions or rethrown them. If a checked exception is rethrown, then the java function has to declare it in its signature. Unchecked exception unline checked doesn’t require any handling. Such design meant that unchecked exceptions can’t be handled and are doomed to be thrown up to the top parent.
There are two ways to process exceptions thrown: Handle it inside the current method or just rethrow it. There is no better way to do it; you might have one parent handler or handle it somehow, e.g. make retry logic.
After the introduction, we can split all exceptions into 3 groups: Checked, Runtime, and Error. The main idea is that each of them would be thrown into different situations. The most optimistical is a Checked exception. The Runtime would belong to a situation with a small chance of recovery. And, the most pessimistic is Error.
Knowing the type of exception class we can potentially answer on next questions:
- How bad the situation is and what the cause of the problem is.
- How to fix the problem.
- Do we need to restart JVM?
- Do we need to rewrite the code?
Knowing the exception class we can predict what possibly went wrong. Thinking over the potential cause we can assume what was the cause of the problem and how to fix it. Let’s review the most popular scenarios and find out what those exceptions can tell us. In the next paragraphs, we review famous exceptions and investigate what was the potential code. In our investigation, we assume that the application is stable enough and the development stage has been completed and tested.
We begin from the most pessimistical case or our Ugly Guy. Is Error really that ugly? Let’s take a look into the most popular Java Errors:
So, in most cases, all you need to do is change JVM config or add the missing dependency. There are still cases that require code changes, but they are less likely in order to apply changes in every situation.
For checked exceptions, we expect that there is a chance to recover the problem; for example, try again. In this part, we review the most famous Checked exceptions. Provided exceptions might be parent for each other, but, here, I list just most popular cases regardless of their relationship:
Okkaay, so a lot of exceptions, but, as I promised, I put here the most popular exceptions. So, what does this table say? If we take a look into the most likely causes we will find out that most of them not just don’t require any code changes but not even an application restart. So, obviously, Checked exceptions deserve to be Good Guy.
The most common and personally the most pessimistic exception: Runtime. Checked and Error exceptions error don’t lead to any code changes. But, Runtime exceptions in most of the cases highlight real problems in the code that can’t be fixed without rewriting the code. Let’s find out why by reviewing the most popular Runtime exceptions:
An example might make an impression that any Runtime exception makes the application doomed. In most cases, it’s correct because the application can’t be recovered without code changes. Eventually, the Runtime exception is our Bad Guy which leads to new code changes, developer’s stress, and business losses.
During this review, we made one heavy assumption: the code is production-ready and well-tested. But, in practice, it’s hardly achievable. So, the conclusions we did are not 100% reliable, but the more the code is stable, the more realistic the results are.
According to the Checked Exception, the Design developer has to make all recoverable exceptions checkable. As a consequence, every call to a method with a checked exception signature adds 3-4 lines for the Try Catch structure. Such an approach makes code ugly and less readable. Personally, I prefer to use Runtime Exceptions. Even in the case of designing a library you are still allowed to keep your Runtime exception in the method signature and put some comments to your API. In that case, your API user will be able to decide how to handle it.