In many of the projects we have worked on, we have seen different ways of coding and various different strategies, code formatting, class naming styles, databases and technologies and blaw blaw. The one thing that was same in all projects were “exceptions”. In nearly all the projects, they had custom exceptions usually created by extending Exception class. I have already talked about exception handling using inner classes, exception handling best practices, asynchronous and synchronous exceptions and ways to effectively handle NullPointerException.
In this post, I am taking forward the discussion on exceptions. I will talk about checked and unchecked exceptions. I will talk about few other things e.g. what actually an exception is and best practices around checked exceptions.
Sections in this post: What is an exception Checked and unchecked exceptions Best practices
What is an exception
When an error occurs within a method, the method creates an object and hands it off to the runtime system. The object, called an exception object, contains information about the error, including its type and the state of the program when the error occurred. Creating an exception object and handing it to the runtime system is called throwing an exception.
You have two choices when this exception object is created in your application. Either your will handle it within method OR you will pass it to the caller method to let it handle. This is very important decision to be made while setting the responsibilities of a method. Also a method should clearly indicate that what all exceptional scenarios it will handle and which it will not.
To handle the exception, you must catch the exception in catch section of try-catch block. If a exception is not handled in your application, then it will propagate to JVM and JVM will usually terminate the program itself.
Checked and unchecked exceptions
In java, exceptions are broadly categorized into two sections: checked exceptions and unchecked exceptions. Let’s explore them.
Checked exceptions denote error scenarios which are outside the immediate control of the program. They occur usually interacting with outside resources/ network resources e.g. database problems, network connection errors, missing files etc.
They are present in java since JDK 1. And java is the first language to introduce this category. At the time, we thought that checked exceptions were a great idea; and yes, they can yield some benefit. However, it is clear now that they aren’t necessary for the production of robust software. C# doesn’t have checked exceptions, and despite valiant attempts, C++ doesn’t either. Neither do Python or Ruby. Yet it is possible to write robust software in all of these languages. Because that is the case, we have to decide—really—whether checked exceptions are worth their price.
Java forces you to handle these error scenarios in some manner in your application code. They will come immediately into your face, once you start compiling your program. You can definitely ignore them and let them pass to JVM, but it’s bad habit. Ideally, you must handle these exceptions at suitable level inside your application so that you can inform the user about failure and ask him to retry/ come later.
Checked Exceptions are subclasses of Exception.
Example of mostly faced checked exceptions are : ClassNotFoundException, IOException, SQLException and so on. Please refer official java documentation for all such classes.
Java also provides UncheckedExceptions, the occurrences of which are not checked by the compiler. They will come into life/occur into your program, once any buggy code is executed. Unchecked exceptions are usually result of bad code in your system. A method is not forced by compiler to declare the unchecked exceptions thrown by its implementation and methods almost always do not declare them.
Unchecked Exceptions are subclasses of RuntimeException.
As a rough rule of thumb, checked exceptions are forced by compiler and used to indicate exceptional conditions that are out of the control of the program (for example, I/O errors), while unchecked exceptions are occurred during runtime and used to indicate programming errors (for example, a null pointer).
Example of mostly faced unchecked exceptions are : ArithmeticException, ArrayStoreException, ClassCastException, ConcurrentModificationException, DOMException, IllegalArgumentException, IllegalMonitorStateException and so on. Please refer official java documentation for all such classes.
- Checked exceptions can be used when a method cannot do what its name says it does. e.g. A method named prepareSystem() which pre-populate config files and do some configuration using them, can declare throwing FileNotFoundException which implies that method uses configuration files from file system. Though it is not recommended approach.
- Checked exceptions ideally should never be used for programming errors, but absolutely should be used for resource errors and for flow control in such cases.
- Throw only exceptions which a method can not handle by any mean. Method should first try to handle it asap it encounters. Throw only if it is not possible to handle in place.
- A good way to define method signatures is to declare exceptions close to method name. If your method is named openFile, then it is expected to throw FileNotFoundException?. If your method is named findProvider, then it is expected to throw NoSuchProviderException. Also, these type of exceptions should be made CheckedExceptions as it forces the caller to deal with the problems that are inherent to the semantic of your methods.
- Principle says that if a client can reasonably be expected to recover from an exception, make it a checked exception. If a client cannot do anything to recover from the exception, make it an unchecked exception. In reality most applications will have to recover from pretty much all exceptions including NullPointerException, IllegalArgumentExceptions and many other unchecked exceptions. The action / transaction that failed will be aborted but the application has to stay alive and be ready to serve the next action / transaction. The only time it is normally legal to shut down an application is during startup. For instance, if a configuration file is missing and the application cannot do anything sensible without it, then it is legal to shut down the application.
Happy Learning !!