When I try to throw an exception in an instance initialization (not class initialization) block I get the error:
initializer must be able to complete normally
Why is it not allowed although Java does it itself?
The following example creates four classes. The class A
fails during instantiation because of an ArithmeticException. This can be and handled with a catch
. The same for B
which fails with a NullPointerException. But when I try to throw a NullPointerException on my own as in C
the program does not compile. And I get the same error when I try to define my own RuntimeException as in D
. So:
How can I do the same as Java does itself?
// -*- compile-command: "javac expr.java && java expr"; -*-
class expr
{
class A
{
int y;
{{ y = 0 / 0; }}
}
class B
{
Integer x = null;
int y;
{{ y = x.intValue(); }}
}
class C
{
{{ throw new NullPointerException(); }}
}
class Rex extends RuntimeException {}
class D
{
{{ throw new Rex(); }}
}
void run ()
{
try { A a = new A(); }
catch (Exception e) { System.out.println (e); }
try { B b = new B(); }
catch (Exception e) { System.out.println (e); }
try { C c = new C(); }
catch (Exception e) { System.out.println (e); }
try { D d = new D(); }
catch (Exception e) { System.out.println (e); }
}
public static void main (String argv[])
{
expr e = new expr();
e.run();
}
}
A static block can throw only a RunTimeException, or there should be a try and catch block to catch a checked exception. A static block occurs when a class is loaded by a class loader.
Java try block is used to enclose the code that might throw an exception. It must be used within the method. If an exception occurs at the particular statement in the try block, the rest of the block code will not execute. So, it is recommended not to keep the code in try block that will not throw an exception.
Instance Initialization Blocks or IIB are used to initialize instance variables . So firstly, constructor is invoked and the java compiler copies the instance initializer block in the constructor after the first statement super(). They run each time when object of the class is created.
You cannot use throws keyword with a static block, and more over a static block is invoked at compile time (at the time of class loading) no method invokes it.
{ throw new Rex(); }
That means that the instance will be never initialized properly. There should be some condition where the instance can be initialized properly. e.g.
{ if(true) { throw new Rex(); } } //It doesn't complain here
If the exception being thrown is a checked-exception then you must add it to the constructor's throws
clause. e.g.
public class MyObject {
{
//...
throw new Exception();
//...
}
public MyObject() throws Exception {
}
}
initializer must be able to complete normally
means that there must be a possible code path that doesn't throw an exception. Your examples unconditionally throw, and are therefore rejected. In the other examples, the static analysis doesn't go far enough to determine that they also throw in all cases.
For example,
public class StaticThrow {
static int foo = 0;
{{ if (Math.sin(3) < 0.5) { throw new ArithmeticException("Heya"); } else { foo = 3; } }}
public static void main(String[] args) {
StaticThrow t = new StaticThrow();
System.out.println(StaticThrow.foo);
}
}
compiles, and when run throws
Exception in thread "main" java.lang.ArithmeticException: Heya
at StaticThrow.<init>(StaticThrow.java:3)
at StaticThrow.main(StaticThrow.java:5)
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