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