I came across some interesting code in java.lang.Class#newInstance0:
// Run constructor
try {
return tmpConstructor.newInstance((Object[])null);
} catch (InvocationTargetException e) {
Unsafe.getUnsafe().throwException(e.getTargetException());
// Not reached
return null;
}
Check out the Unsafe.getUnsafe().throwException
statement. It looks like a checked exception is being thrown from a method which doesn't declare it to be thrown!
Why did they do this?
If the Sun developers can use this technique, is it ok for us to do so as well?
With Java and generics, you can profit from type erasure and just throw any exception with this simple trick:
public class Test {
public static void main(String[] args) {
doThrow(new SQLException());
}
public static void doThrow(Exception e) {
Test.<RuntimeException> doThrow0(e);
}
@SuppressWarnings("unchecked")
public static <E extends Exception> void doThrow0(Exception e) throws E {
throw (E) e;
}
}
Kinda scary, though...
Why did they do this?
I'm not entirely sure, but I expect there was a really good reason. (When you drill down through the layers, reflective invocation involves some extremely tricky things ...)
If the Sun developers can use this technique, is it ok for us to do so as well?
I'd say no ... unless you have a really, really good reason. Methods that throw checked exceptions without declaring them are violating the principle of least surprise. Think of the poor guy who might have to debug your code in a critical production system at 3am.
Just cos' some Sun engineer decided something was a good idea in a particular context, doesn't necessarily make it a good idea in general.
There is an interesting blog on Avoiding Checked Exeptions by Don Schwarz. Thanks for sharing.
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