public class StaticException1 { public static void main(String[] args) { new Obj(); } } class Obj { static { if (1 == 1 + 0) { // tricking the compiler throw new RuntimeException(); } } }This results in
Exception in thread "main" java.lang.ExceptionInInitializerError
at StaticException1.main(StaticException1.java:3)
Caused by: java.lang.RuntimeException
at Obj.(StaticException1.java:10)
... 1 more
Catching ExceptionInInitializerError
ExceptionInInitializerError is an error, but as all errors it can be caught using an appropriate catchcatch(ExceptionInInitializerError e)
, catch(Error e)
or catch(Throwable t)
.public class StaticException2 { public static void main(String[] args) { try { new Obj2(); } catch (ExceptionInInitializerError e) { System.err.println("caught in a static block "+e.getCause()); // do something } System.out.println("going ahead"); } } class Obj2 { static { if (1 == 1 + 0) { // tricking the compiler throw new RuntimeException(); } } }
Recovering from ExceptionInInitializerError
Although ExceptionInInitializerError can be caught, it is actually impossible to recover from it, because the class in which the exception occured is made unavailable for further use (such as instantiating the class), yielding a NoClassDefFoundError.
public class StaticException2 {
public static void main(String[] args) {
try {
new Obj2();
} catch (ExceptionInInitializerError e) {
System.err.println("caught in a static block "+e.getCause());
// do something
}
////////////////////////
// using Obj2 again
new Obj2();
}
}
class Obj2 {
static {
if (1 == 1 + 0) { // tricking the compiler
throw new RuntimeException();
}
}
}
caught in a static block java.lang.RuntimeException
Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class Obj2
at StaticException2.main(StaticException2.java:12)
Consequently, ExceptionInInitializerError is actually unrecoverable, and it is a hard contract that static blocks never throw exceptions.Open question: one may play with the class loader to overcome this, how?