Throw Checked Exceptions Like Runtime Exceptions in Java
How to throw a checked exception without catch block or throws clause in Java? Simple!
public class Test {
// No throws clause here
public static void main(String[] args) {
doThrow(new SQLException());
}
static void doThrow(Exception e) {
Test.<RuntimeException> doThrow0(e);
}
@SuppressWarnings("unchecked")
static <E extends Exception> void doThrow0(Exception e) throws E {
throw (E) e;
}
}
Due to generic type erasure, the compiler will compile something here that really shouldn’t compile. Crazy? Yes. Scary? Definitely!
The generated bytecode for doThrow() and doThrow0() can be seen here:
// Method descriptor #22 (Ljava/lang/Exception;)V
// Stack: 1, Locals: 1
static void doThrow(java.lang.Exception e);
0 aload_0 [e]
1 invokestatic Test.doThrow0(java.lang.Exception) : void [25]
4 return
Line numbers:
[pc: 0, line: 11]
[pc: 4, line: 12]
Local variable table:
[pc: 0, pc: 5] local: e index: 0 type: java.lang.Exception
// Method descriptor #22 (Ljava/lang/Exception;)V
// Signature: <E:Ljava/lang/Exception;>(Ljava/lang/Exception;)V^TE;
// Stack: 1, Locals: 1
static void doThrow0(java.lang.Exception e) throws java.lang.Exception;
0 aload_0 [e]
1 athrow
Line numbers:
[pc: 0, line: 16]
Local variable table:
[pc: 0, pc: 2] local: e index: 0 type: java.lang.ExceptionAs can be seen, the JVM doesn't seem to have a problem with the checked exception thrown from doThrow0(). In other words, checked and unchecked exceptions are mere syntactic sugar
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)
Tags:






Comments
Sinuhé Pop replied on Fri, 2012/09/21 - 8:25am
Vitalii Tymchyshyn replied on Sun, 2012/09/23 - 2:18am
Generics are simply syntaxis sugar. You should get ClassCastException in runtime, much like here:
Vitalii Tymchyshyn replied on Sun, 2012/09/23 - 2:23am
in response to:
Vitalii Tymchyshyn
Sandeep Kadyan replied on Sun, 2012/09/23 - 7:05am
in response to:
Vitalii Tymchyshyn
Orlin Gueorguiev replied on Mon, 2012/09/24 - 8:35am
in response to:
Vitalii Tymchyshyn
Lukas Eder replied on Tue, 2012/09/25 - 2:46am
in response to:
Vitalii Tymchyshyn
Vitalii Tymchyshyn replied on Tue, 2012/09/25 - 3:23am
in response to:
Lukas Eder
try{ someCall() } catch (RuntimeException e) { handle(); }And now someCall starts to throw, say, IOException. This won't be catched and handled.Lukas Eder replied on Tue, 2012/09/25 - 3:36am
in response to:
Vitalii Tymchyshyn
So? I doubt that it's a bug. Throwing checked exceptions had always been possible in Java. For instance using sun.misc.Unsafe.throwException(Throwable).
Some examples can be seen here:
http://stackoverflow.com/q/4375828/521799
Vitalii Tymchyshyn replied on Tue, 2012/09/25 - 4:09am
in response to:
Lukas Eder
Anything that works against JLS is either bug or hack. As for me, to qualify for a hack, scenario should be either noted as unsafe (e.g. accessing private members with reflection) or be vendor extension (like sun.misc.Unsafe). The method shown here is not a hack. This means it's a bug because it violates JLS.
Lukas Eder replied on Tue, 2012/09/25 - 5:04am
in response to:
Vitalii Tymchyshyn
But it isn't really a checked exception. By the fact that doThrow0()'s <E extends Exception> is bound to RuntimeException, no throws clause is necessary in doThrow().
The fact that RuntimeException is assignment-compatible to Exception means that there is no cast necessary.
I'm not sure if this is a bug in the compiler. Probably a lack of specification in the JLS, though, handling this corner-case...
I find this quite intriguing. Feel free to argue for your case on the Stack Overflow question that I've created just now:
http://stackoverflow.com/q/12580598/521799
Vitalii Tymchyshyn replied on Tue, 2012/09/25 - 5:42am
in response to:
Lukas Eder