Your InnerClass
is an inner class .
An inner class is a nested class that is explicitly or implicitly declared static
.
Inner classes may contain instances
Example i
direct inner class C
[your InnerClass
] class or interface O
[your OuterClass
] is associated with an instance of O
, known as a direct instance of i
.
Only inner classes declared in static contexts do not contain instances.
An instance of inner class i
whose declaration occurs in a static context does not have lexically-closing instances.
Your inner example class is not in a static context, so it requires an enclosing instance.
The Java language specification then indicates
The constructor of a nonunit inner member class implicitly declares a variable representing the immediately including instance of the class as the first formal parameter
(More on why, if you're interested). In other words, your InnerClass
constructor really looks like
public InnerClass(OuterClass OuterClass.this){} // this is valid syntax for entirely different reasons
It expects an argument of type OuterClass
to use as its instance. Subclassing this type of InnerClass
does not change this, moreover, any subtype must refer to a super-super super constructor.
For constructors, the specification also indicates
If the constructor body does not start with an explicit constructor call and the declared constructor is not part of the primordial class Object
, then the constructor body implicitly begins with a call to the constructor of the superclass "super ();" , calling the constructor of its direct superclass that takes no arguments.
So, without a parameter, your code will not work
public class Clazz extends OuterClass.InnerClass { public Clazz() {
This super()
constructor call does not work. In this case, this is because it is the wrong syntax. But the idea is that the superconstructor expects an argument for a formal parameter representing the spanning instance, but you do not provide it. The correct syntax is the one you already have. Let him determine it.
There are several types of constructor calls . Your
public Clazz(OuterClass outerClass) { outerClass.super(); }
is a qualified call to the superclass constructor, defined as
Qualified superclass constructor calls start with a Primary
expression or ExpressionName
. They allow the constructor of the subclass to explicitly specify a newly created object that immediately includes an instance relative to the direct superclass (ยง8.1.3). This may be necessary when the superclass is an inner class.
The chapter explains how the expression is evaluated.
If the call to the superclass constructor is qualified, then Primary
or ExpressionName
immediately preceding " .super
", p
. [...]
Otherwise, the result of this evaluation will immediately include instance i
relative to S
In other words, the object referenced by OuterClass
becomes the required instance of your Clazz
instance.
In simplified expressions, ignoring the case of inner classes, your example comes down to something like
public class Foo {} public class Bar { public Bar(Foo foo){} } public class SubBar extends Bar { public SubBar(Foo foo) { super(foo); } }
SubBar
must satisfy the super constructor Bar
, which expects an instance of Foo
. This is the same as your Clazz
type, with the exception of its supertype constructor, implicit.