Java Reference
In-Depth Information
Exception in thread "main" InstantiationException: Outer$Inner
at java.lang.Class.newInstance0(Class.java:335)
at java.lang.Class.newInstance(Class.java:303)
at Outer.greetWorld(Outer.java:7)
at Outer.main(Outer.java:3)
Why would this exception be thrown? As of release 5.0, the documentation for Class.newInstance
says that it throws InstantiationException if the Class object "represents an abstract class, an
interface, an array class, a primitive type, or void; or if the class has no nullary [in other words,
parameterless] constructor; or if the instantiation fails for some other reason" [Java-API] . Which of
these conditions apply? Unfortunately, the exception message fails to provide even a hint.
Only the last two of these reasons could possibly apply: Either Outer.Inner has no nullary
constructor or the instantiation failed "for some other reason." When a class has no explicit
constructor, as is the case for Outer.Inner , Java automatically provides a default public constructor
that takes no parameters [JLS 8.8.9], so there should be a nullary constructor. Nevertheless, the
newInstance invocation fails because Outer.Inner has no nullary constructor!
The constructor of a non-static nested class is compiled such that it has as its first parameter an
additional implicit parameter representing the immediately enclosing instance [JLS 13.1]. This
parameter is passed implicitly when you invoke the constructor from any point in the code where
the compiler can find an appropriate enclosing instance. But this applies only when you invoke the
constructor normally: nonreflectively. When you invoke the constructor reflectively, this implicit
parameter must be passed explicitly, which is impossible with Class.newInstance . The only way
to pass this implicit parameter is to use java.lang.reflect.Constructor . When this change is
made to the program, it prints Hello world as expected:
private void greetWorld() throws Exception {
Constructor c = Inner.class.getConstructor(Outer.class);
System.out.println(c.newInstance(Outer.this));
}
Alternatively, you might observe that Inner instances have no need for an enclosing Outer instance
and so declare the class Inner to be static . Unless you have a compelling need for an enclosing
instance, prefer static member classes over nonstatic [EJ Item 18]. This simple change will fix
the program:
 
 
Search WWH ::




Custom Search