Evil Behavior with Unchecked Checked Exceptions
Anders Nordås shows how to throw a checked exception without declaring a throws clause. The method uses some inherently evil mechanisms (the name of the class “sun.misc.Unsafe” should be a tip of), and like Anders says, this should probably never be used in production. Basically, calling sun.misc.Unsafe.throwException
will throw a checked exception without alerting the compiler. The exception is not wrapped, but it cannot be caught by its class name, as it is not declared. Here is some code to illustrate:
public class PureEvilness {
public static void throwIt(IOException exception) {
// See Anders' blog for implementation
// Notice: No "throws" clause!
}
public static void main(String[] args) {
/*
* Error: "Unreachable catch block for IOException.
* This exception is never thrown from the try statement block"
try {
throwIt(new IOException());
} catch (IOException e) {
// Deal
}
*/
try {
throwIt(new IOException());
} catch (Exception e) {
if (e.getClass() == IOException.class) {
System.err.println("It was an IOException!");
}
// Deal
}
}
}
The wonders of checked exceptions never cease.
Comments:
Johannes Brodwall - Jul 19, 2007
Hi, Harald
The code as it stands doesn’t work. I expect the template code was eaten by the HTML-izer of both my blog and/or crazy bob’s blog. Here is the correct code:
public static void throwIt2(final Throwable exception) {
class Thrower<T extends Throwable> {
private void sneakyThrow(Throwable exception) throws T {
throw (T)exception;
}
}
new Thrower<RuntimeException>().sneakyThrow(exception);
}
I don’t even get a compiler warning. This is a very neat trick.
[.k] - Jul 17, 2007
It can actually be a lot easier than Anders’ example. See this http://weblogs.java.net/blog/crazybob/archive/2004/09/dont_try_this_a.html for even more clever implementations. :-)
I propose a utility-class with something like this, and we’re good to go:
public static void throwUnchecked(final Throwable pException) { // Type parameter to Thrower is erased at compile-time new Thrower().sneakyThrow(pException); }
private static class Thrower { private void sneakyThrow(Throwable pException) throws T { throw (T) pException; // Unchecked cast } }
I’m starting to think this might be useful.. Or… Maybe I’m just tired.. :-P
.k