I find Java's exception hierarchy confusing. Throwable
is divided into Error
and Exception
, and RuntimeException
inherits from Exception
.
Error
is an unchecked exception. Why doesn't Error
inherit from RuntimeException
then?
Exception
is a checked exception. RuntimeException
is an unchecked exception, yet it inherits from Exception
. Doesn't this violate the Liskov-Substitution-Principle?
Wouldn't it make more sense if Throwable
were divided into Exception
(checked) and RuntimeException
(unchecked), and Error
would inherit from RuntimeExeption
?
I find Java's exception hierarchy confusing. Throwable is divided into Error and Exception, and RuntimeException inherits from Exception.
A Throwable
is anything that can be used to unwind the call stack. This should include some VM level fault (flagged by an Error) and something application specific (flagged by an Exception)
Error
is an unchecked exception. Why doesn't Error inherit from RuntimeException then?
Simply because Errors are not Exceptions. There wouldn't be any point in actually "catching" an Error. For eg. What would you do after catching an OutOfMemoryError
. Errors are meant to flag something seriously happened at the VM level which is not necessarily handle-able by the programmer
Exception is a checked exception. RuntimeException is an unchecked exception, yet it inherits from Exception. Doesn't this violate the Liskov-Substitution-Principle?
Not really. What the implementors were trying to say was that Exceptions MUST always be checked. Your code will be cleaner if all your methods declare what sort of application/library Exceptions they throw. RuntimeExceptions should only be thrown in case of more general / dynamic situations such as a NullPointerException
where the developer might not have coded for the case but is a serious bug which is not exactly something mentioned in the application spec.