The Java specification requires that if an exception is thrown, it is either handled by a try/catch statement, or that the function is declared with "throws XYZException". This has the exception of RuntimeException, where it is OK if this is thrown without being caught.
This might sound like a matter of opinion, but the more I think about it, the more it seems really counter-intuitive:
Why is it that we have a RuntimeException extending Exception?
When I first started doing Java, I thought ALL exceptions had to be caught in that way, and it made sense because all exceptions extend Exception. It seems like a violation of OOP to have a RuntimeException exception exception :P. Since RuntimeException makes throws kinda redundant, why didn't Java allow all exceptions at runtime in the first place, adding a throws only when you want to force the caller to handle that type of exception?
Examples:
void noThrows() {
throw new Exception();
}
... no errors.
void hasThrows() throws AnyBaseOfXYZException {
throw new XYZException();
}
... no errors.
void testFunction() {
hasThrows();
}
... fails since "hasThrows" throws AnyBaseOfXYZException, and this is not handled
void testFunction() {
try {
hasThrows();
} catch (AnyBaseOfXYZException e) {
...
}
}
... no errors.
I'd thought about maybe some kind of "CompileTimeException" that extends Exception, but when you give it enough thought, it just can't work without being as ugly as RuntimeException.
Basically, why did Java decide to force all exceptions to require throws
except for RuntimeExceptions, when all exceptions could be runtime exceptions except when otherwise stated with throws
?
Class RuntimeException. RuntimeException is the superclass of those exceptions that can be thrown during the normal operation of the Java Virtual Machine. RuntimeException and its subclasses are unchecked exceptions.
All unchecked exceptions base class is Runtime Exception so the compiler will never check anywhere else than RuntimeException and its subclasses.
Runtime exceptions represent problems that are the result of a programming problem and as such, the API client code cannot reasonably be expected to recover from them or to handle them in any way. With the Exceptions you must catch it explicitly because you can still do something to recover.
If both base and derived classes are caught as exceptions, then the catch block of the derived class must appear before the base class.
Firstly, the base class of all things that can be thrown is Throwable
(not Exception
).
Under Throwable
are two subclasses: Exception
and Error
.
Under Exception
is RuntimeException
.
Of these 4 main classes, RuntimeException
and Error
are unchecked (may be thrown without having to be declared as being thrown).
The idea behind RuntimeException
being unchecked is that it's typically a programming error and that normal good practice should avoid them (eg ArrayIndexOutOfBoundsException
or NullPointerException
) and to require them to be caught would clutter up the code massively.
The reason Errors
are unchecked is that basically, there's nothing you can to about it if one happens, eg OutOfMemoryError
etc.
That leaves all other Throwables, ie subclasses of Exception
, must be declared as thrown or caught. The idea behind this is that checked exceptions can be "handled by the caller". eg FileNotFoundException
(we know what this means and should know what to do if we get one).
The Java designers didn't always get this right. SQLException
is checked, but there's no realistic way to recover - do I have a syntax error in my query? is the database refusing conections? who knows, but I do know I can't "handle" it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With