Exception Hierarchy
Exceptions have a common root
Exceptional situations in Java are represented by objects, and their types form a regular inheritance hierarchy.
At its base is the Throwable class.
Java can use objects of this class and its subclasses as exceptional situations.
Object
└── Throwable
├── Error
└── Exception
└── RuntimeException
Throwable has two main branches: Error
and Exception. They are on the same level and represent different categories of problems.
Error and Exception are different branches
Error is used for serious runtime environment problems
that an ordinary application generally does not try to treat as an expected situation.
Examples from this branch include OutOfMemoryError
and StackOverflowError.
Exception is the branch for situations that application code usually associates
with the concept of an “exception.” It has many subclasses describing different kinds of problems.
Error is not a kind of Exception.
Both classes, directly or through their branches, lead back to Throwable.
So the statement “all errors are Exceptions” is incorrect.
Where RuntimeException fits
RuntimeException is located inside the Exception branch.
Many familiar exceptions inherit from it: NullPointerException,
IllegalArgumentException, IndexOutOfBoundsException, and others.
Exception
└── RuntimeException
├── NullPointerException
├── IllegalArgumentException
└── IndexOutOfBoundsException
The position of RuntimeException in this hierarchy will later help explain
why Java treats different groups of exceptions differently.
We will cover checked and unchecked exceptions in detail in a separate topic.
The hierarchy follows normal inheritance rules
The familiar rules of polymorphism apply here: an object of a subclass can be stored in a variable whose type is one of its ancestors.
For example, IllegalArgumentException is also a
RuntimeException, Exception, and Throwable.
RuntimeException first = new IllegalArgumentException("Wrong value");
Exception second = new IllegalArgumentException("Wrong value");
Throwable third = new IllegalArgumentException("Wrong value");
The higher a type is in the tree, the more different subclasses it groups together. That is why understanding this structure will matter later: exception-handling constructs rely not only on the specific class of a problem, but also on its place in the hierarchy.