Understanding Checked VS Unchecked Exceptions in Java

Understanding checked vs unchecked exceptions in Java

Many people say that checked exceptions (i.e. these that you should explicitly catch or rethrow) should not be used at all. They were eliminated in C# for example, and most languages don't have them. So you can always throw a subclass of RuntimeException (unchecked exception)

However, I think checked exceptions are useful - they are used when you want to force the user of your API to think how to handle the exceptional situation (if it is recoverable). It's just that checked exceptions are overused in the Java platform, which makes people hate them.

Here's my extended view on the topic.

As for the particular questions:

  1. Is the NumberFormatException consider a checked exception?

    No. NumberFormatException is unchecked (= is subclass of RuntimeException). Why? I don't know. (but there should have been a method isValidInteger(..))

  2. Is RuntimeException an unchecked exception?

    Yes, exactly.

  3. What should I do here?

    It depends on where this code is and what you want to happen. If it is in the UI layer - catch it and show a warning; if it's in the service layer - don't catch it at all - let it bubble. Just don't swallow the exception. If an exception occurs in most of the cases you should choose one of these:

    • log it and return
    • rethrow it (declare it to be thrown by the method)
    • construct a new exception by passing the current one in constructor
  4. Now, couldn't the above code also be a checked exception? I can try to recover the situation like this? Can I?

    It could've been. But nothing stops you from catching the unchecked exception as well

  5. Why do people add class Exception in the throws clause?

    Most often because people are lazy to consider what to catch and what to rethrow. Throwing Exception is a bad practice and should be avoided.

Alas, there is no single rule to let you determine when to catch, when to rethrow, when to use checked and when to use unchecked exceptions. I agree this causes much confusion and a lot of bad code. The general principle is stated by Bloch (you quoted a part of it). And the general principle is to rethrow an exception to the layer where you can handle it.

Checked vs Unchecked Exceptions in Java

CheckedException needs to be handled by the caller, Unchecked exception don't.

So, when you design your application you should take in mind what kind of exceptional situation you are managing.

For example, if you design a validation method that checks the validity of some user input, then you know that the caller must check the validation exception and display the errors to the user in a nice looking way. This should be a checked exception.

Or, for those exceptional conditions that can be recovered: imagine you have a load balancer and you want notify the caller that one of the "n" servers is down, so the caller must recover the incident re-routing the message to another server; this should be a checked exception, because it is crucial that the caller (client) tries to recover the error, and don't just let the error to break the program flow.

Instead, there are many conditions that should not happen, and/or should instead break the program. For example, a programming error (like division by zero, null pointer exception), a wrong usage of an API (IllegalStateException, OperationNotSupportedException), an hardware crash, or just some minor situation that are not recoverable (lost connection to a server), or a doomsday :-) ; in those cases, the normal handling is to let the exception reach the most outer block of your code that displays to the user that an unpredictable error has occurred and the application can't do nothing to continue. It's a a fatal condition, so the only thing you can do is to print it to the logs or showing it to the user in the user interface. In those cases, catching the exception is wrong, because, after catching the exception you need to manually stop the program to avoid further damages; so it could be better to let some kind of exception "hit the fan" :)

For those reasons there are some exceptions that are Unchecked also in the JRE: OutOfMemoryError (unrecoverable), NullPointerException (it's a bug that needs to be fixed), ArrayIndexOutOfBoundsException (another bug example), and so on.

I personally think that also SQLException should be unchecked, since it denotes a bug in the program, or a connection problem to the database. But there are many examples where you get exception that you really don't have any clue in how to manage (RemoteException).

The best way to handle exceptions are: if you can recover or manage the exception, handle it. Otherwise let the exception pass out; somebody else will need to handle. If you are the last "somebody else" and you don't know how to handle an exception, just display it (log or display in the UI).

How do you judge whether to make an exception checked or unchecked?

The meaning of the quote is this: If the client code can not recover from the problem, it needs to let the exception propagate to higher layers. If you use checked exceptions for that, you need to declare the checked exception through all call layers without benefit.

To rephrase the quote: If the exception is expected to propagate through the layers, make it unchecked. Only make it checked if the caller can actually do something about it.

When to choose checked and unchecked exceptions

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).

Java example for checked vs unchecked exception

No it is not a valid example / illustration. In both cases the exception that is thrown is an unchecked exception.

The difference between checked exceptions and unchecked exceptions is the exception class.

  • ArithmeticException is always an unchecked exception because it extends RuntimeException

  • IOException is a checked exception because it does not extend RuntimeException (or Error).

The fact that you do or don't catch the exception doesn't change its nature.


At the risk of repeating myself:

Unchecked Exception: The exceptions that are not checked at compile time are called unchecked exceptions.

Checked Exception: The exceptions that are checked at compile time are called Checked exceptions.

These are both incorrect definitions.


See also: Java: checked vs unchecked exception explanation

Comparing checked and unchecked exceptions (Performance, Benchmarks) in Java

From the perfomance point of view, building stack trace for exception is anyway the longest operation when an exception is generated (details).

Checked and unchecked exceptions make difference only at compile time. The Java compiler forces you to either catch checked exceptions or declare them in the method signature. It was supposed to improve program safety, but the majority opinion seems to be that it's not worth the design problems it creates.

There is even Lomboks "magical" @SneakyThrows annotation to overcome this compile-time check. On the JVM (class file) level, all exceptions, checked or not, can be thrown regardless of the throws clause of your methods, which is why this works.

Java - checked vs unchecked Exception - tell from code alone?

Is it possible to tell if an exception class is a checked or unchecked just by looking at the code?

Yes. If you know the rules ... as specified in the JLS (11.1.1) ... and you can also see the code of the exceptions' superclasses (so that you can check the hierarchy).

The rules are that exceptions are "checked" except for the following:

  • RuntimeException and its subclasses, and

  • Error and its subclasses,

which are "unchecked".

I wonder if the difference is defined inside the interpreter itself?

No. It is in the Java Language Spec. In fact, the JVM treats checked and unchecked exceptions the same. All the checking that checked exceptions are treated correctly is done by the Java compiler.


However, I still do not understand the reasoning that RuntimeException extends Exception rather than Throwable. That design choice seems contradictory, given that there is nothing in RuntimeException that overrides behavior defined in Exception.

It is the way it is. And besides, I don't see any logical contradiction.

  • An Error represents an unrecoverable condition. It is unchecked because there is no point forcing the application to do something about it.

  • An Exception represents a potentially recoverable condition.

  • A RuntimeException represents a potentially recoverable condition that we don't want to force the application to deal with. (But it could, if it wanted to).

Clearly, by this taxonomy, a RuntimeException >>is<< an Exception and >>not<< an Error ... and that is the rationale for defining the exception class hierarchy that way.



Related Topics



Leave a reply



Submit