Differences between Runtime/Checked/Unchecked/Error/Exception
Since I am a new Java developer, I have also faced some difficulties for distinguishing and dealing with different types of exceptions. That is why I have made a short note on this topic, and whenever I get confused I go through it. Here it is with the image of the Throwable
class hierarchy:
[image courtesy of JavaTpoint].
There are three key classes to remember here: Throwable
, Exception
and Error
. Among these classes Exception
can be divided into two types: "Checked Exception" and "Unchecked Exception".
Checked Exception:
- These are the classes that extend
Throwable
exceptRuntimeException
andError
. - They are also known as compile time exceptions because they are checked at compile time, meaning the compiler forces us to either handle them with
try/catch
or indicate in the function signature that itthrows
them and forcing us to deal with them in the caller. - They are programmatically recoverable problems which are caused by unexpected conditions outside the control of the code (e.g. database down, file I/O error, wrong input, etc).
- Example:
IOException
,SQLException
, etc.
Unchecked Exception:
- The classes that extend
RuntimeException
are known as unchecked exceptions. - Unchecked exceptions are not checked at compile-time, but rather at runtime, hence the name.
- They are also programmatically recoverable problems but unlike checked exception they are caused by faults in code flow or configuration.
- Example:
ArithmeticException
,NullPointerException
,ArrayIndexOutOfBoundsException
, etc. - Since they are programming errors, they can be avoided by nicely/wisely coding. For example "dividing by zero" produces an
ArithmeticException
, which can be avoided by a simple check on the divisor. Similarly we can avoidNullPointerException
by simply checking the references:if (object != null)
or even using better techniques.
Error:
Error
refers to an irrecoverable situation that is not being handled by atry/catch
.- Example:
OutOfMemoryError
,VirtualMachineError
,AssertionError
, etc.
Why are these many types?
In addition to Stephen C's answer I want to say:
exception handling is a relatively expensive operation in Java. We should not put all exceptional situation in a try/catch
block. Excessive use of try/catch
s may hamper program performance.
In conclusion, Exception
s should be handled programmatically whenever possible. On the other hand, we cannot handle Error
s, so these might be some logical reasons why there are many types of exceptions.
Throwable is at the top off all exceptions. Underneath Throwable you have Error and Exception. Underneath Exception you have RuntimeException.
Java has two types of exceptions - checked and unchecked. Checked exceptions are enforced by the compiler (you have to declare them in the throws clause and catch them eventually). Unchecked exceptions are not enforced for catching or declaring in throws clause.
(Controversial part of the answer)
Throwable exists so that there is a parent for all exception types. You should never declare that you throw Throwable and never catch it (unless you really really really know what you are doing).
Error exists to indicate issues with the runtime environment, things that your program probably cannot recover from, such as a badly formatted class file or the VM running out of memory. You should not catch an Error unless you really know what you are doing.
Exception exists as the root for all non-programmer errors (see RuntimeException for the "exception" to this) , such as a file cannot be created because the disk is full. You should not throw, throws, or catch Exception. If you have to catch Exception make sure you know what you are doing.
RuntimeException exists to indicate all programmer error, such as going past the end of an array or calling a method on a null object. These are things that you should fix so that they do not throw exceptions - the indicate that you, the programmer, screwed up the code. Again, you should not catch these unless you know what you are doing.