Java Reference
In-Depth Information
super(); // invokes Inner1() constructor
^
Because the superclass of
Inner2
is itself an inner class, an obscure language rule comes into play.
As you know, the instantiation of an inner class, such as
Inner1
, requires an enclosing instance to
be supplied to the constructor. Normally, it is supplied implicitly, but it can also be supplied
explicitly with a
superclass constructor invocation
of the form
expression.super(args)
[JLS
8.8.7].
If the enclosing instance is supplied implicitly, the compiler generates the expression: It uses the
this
reference for the innermost enclosing class of which the superclass is a member. This is,
admittedly, quite a mouthful, but it is what the compiler does. In this case, the superclass is
Inner1
.
Because the current class,
Inner2
, extends
Outer
indirectly, it has
Inner1
as an inherited member.
Therefore, the qualifying expression for the superclass constructor is simply
this
. The compiler
supplies an enclosing instance, rewriting
super
to
this.super
. Had we done this ourselves, the
compilation error would have made even more sense:
Outer.java:12: cannot reference this before
supertype constructor has been called
this.super();
^
Now the problem is clear: The default
Inner2
constructor attempts to reference
this
before the
superclass constructor has been called, which is illegal [JLS 8.8.7.1]. The brute-force way to fix this
problem is to provide the reasonable enclosing instance explicitly:
public class Outer {
class Inner1 extends Outer { }
class Inner2 extends Inner1 {
public Inner2() {
Outer.this
.super();
}
Search WWH ::
Custom Search