In the following code, what is super keyword referencing to?
class A { int i1 = 10; A() { System.out.println("class A"); } } class B extends A { int i2 = super.i1; B() { System.out.println("class B"); } } class C extends B { int i3 = super.i2; public static void main(String args[]) { C c = new C(); System.out.println(c.i3); } }
If no objects/instances of super class are created, then what is super keyword referencing to as it is a reference variable and supposed to reference super class instance?
Advertisement
Answer
Note that super
is a bit different from this
, in that super
is not a primary expression. In fact, super
is not an expression at all. So it makes little sense to say that super
itself refers to anything. Note that you can’t do:
SomeType foo = super;
What does make sense, are these (not an exhaustive list of everything that involves super
):
- superclass constructor calls of the form
super(...);
- field access of the form
super.identifier
- method call of the form
super.identifier(...)
Those forms all refer to different things, but the word super
itself has no single meaning, unless you are satisfied with “something to do with the superclass”.
Specifically in this question, you are asking about field access. This is described in section 15.11.2 of the language specification.
The form
super.Identifier
refers to the field namedIdentifier
of the current object, but with the current object viewed as an instance of the superclass of the current class.
For i1
, since B
inherits from A
, i1
will refer to the same field even if you view the current object as a B
, so it doesn’t matter what class you view the current object as. Whether it is super.i1
, or this.i1
, or just i1
, doesn’t make a difference. The difference is more apparent when you redeclare i1
in B
:
class A { int i1 = 10; } class B extends A { int i1 = 20; int i2 = super.i1; }
i2
will get the value of 10, rather than 20
, because you viewed the current object as an A
. Note that in this case, an instance of B
gets two fields called i1
, one inherited from A
, and one declared in B
. Viewing the object “as an A
” will let you see the one inherited from A
, otherwise it is hidden.