In Java, methods that throw checked exceptions (Exception or its subtypes - IOException, InterruptedException, etc) must declare throws sta
The issue here is that checked/unchecked exception limitations affect what your code is allowed to throw, not what it's allowed to catch. While you can still catch any type of Exception
, the only ones you're allowed to actually throw again are unchecked ones. (This is why casting your unchecked exception into a checked exception breaks your code.)
Catching an unchecked exception with Exception
is valid, because unchecked exceptions (a.k.a. RuntimeException
s) are a subclass of Exception, and it follows standard polymorphism rules; it doesn't turn the caught exception into an Exception
, just as storing a String
in an Object
doesn't turn the String
into an Object
. Polymorphism means that a variable that can hold an Object
can hold anything derived from Object
(such as a String
). Likewise, as Exception
is the superclass of all exception types, a variable of type Exception
can hold any class derived from Exception
, without turning the object into an Exception
. Consider this:
import java.lang.*;
// ...
public String iReturnAString() { return "Consider this!"; }
// ...
Object o = iReturnAString();
Despite the variable's type being Object
, o
still stores a String
, does it not? Likewise, in your code:
try {
safeMethod();
} catch (Exception e) { // catching checked exception
throw e; // so I can throw... a checked Exception?
}
What this means is actually "catch anything compatible with class Exception
(i.e. Exception
and anything derived from it)." Similar logic is used in other languages, as well; for example, in C++, catching a std::exception
will also catch std::runtime_error
, std::logic_error
, std::bad_alloc
, any properly-defined user-created exceptions, and so on, because they all derive from std::exception
.
tl;dr: You're not catching checked exceptions, you're catching any exceptions. The exception only becomes a checked exception if you cast it into a checked exception type.