Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to choose checked and unchecked exceptions

In Java (or any other language with checked exceptions), when creating your own exception class, how do you decide whether it should be checked or unchecked?

My instinct is to say that a checked exception would be called for in cases where the caller might be able to recover in some productive way, where as an unchecked exception would be more for unrecoverable cases, but I'd be interested in other's thoughts.

like image 506
Matt Sheppard Avatar asked Aug 26 '08 08:08

Matt Sheppard


People also ask

Should I use checked or unchecked exception?

“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 this way, we can recover the system by accepting another user input file name.

When would use an unchecked exception?

Unchecked exceptions result from faulty logic that can occur anywhere in a software program. For example, if a developer invokes a method on a null object, an unchecked NullPointerException occurs.

Why do we need checked and unchecked exceptions?

A checked exception must be handled either by re-throwing or with a try catch block, a runtime isn't required to be handled. An unchecked exception is a programming error and are fatal, whereas a checked exception is an exception condition within your codes logic and can be recovered or retried from.

Why do we need checked exceptions in Java?

Checked Exceptions. Java checked exceptions are those exceptions, as the name suggests, which a method must handle in its body or throw to the caller method so the caller method can handle it. Checked exceptions are checked by the Java compiler so they are called compile time exceptions.


1 Answers

Checked Exceptions are great, so long as you understand when they should be used. The Java core API fails to follow these rules for SQLException (and sometimes for IOException) which is why they are so terrible.

Checked Exceptions should be used for predictable, but unpreventable errors that are reasonable to recover from.

Unchecked Exceptions should be used for everything else.

I'll break this down for you, because most people misunderstand what this means.

  1. Predictable but unpreventable: The caller did everything within their power to validate the input parameters, but some condition outside their control has caused the operation to fail. For example, you try reading a file but someone deletes it between the time you check if it exists and the time the read operation begins. By declaring a checked exception, you are telling the caller to anticipate this failure.
  2. Reasonable to recover from: There is no point telling callers to anticipate exceptions that they cannot recover from. If a user attempts to read from an non-existing file, the caller can prompt them for a new filename. On the other hand, if the method fails due to a programming bug (invalid method arguments or buggy method implementation) there is nothing the application can do to fix the problem in mid-execution. The best it can do is log the problem and wait for the developer to fix it at a later time.

Unless the exception you are throwing meets all of the above conditions it should use an Unchecked Exception.

Reevaluate at every level: Sometimes the method catching the checked exception isn't the right place to handle the error. In that case, consider what is reasonable for your own callers. If the exception is predictable, unpreventable and reasonable for them to recover from then you should throw a checked exception yourself. If not, you should wrap the exception in an unchecked exception. If you follow this rule you will find yourself converting checked exceptions to unchecked exceptions and vice versa depending on what layer you are in.

For both checked and unchecked exceptions, use the right abstraction level. For example, a code repository with two different implementations (database and filesystem) should avoid exposing implementation-specific details by throwing SQLException or IOException. Instead, it should wrap the exception in an abstraction that spans all implementations (e.g. RepositoryException).

like image 81
Gili Avatar answered Oct 19 '22 07:10

Gili