Difficulty: Beginner
What are the this and super keywords used for in Java? Predict the output of the given parent-child code.
Both this and super are references that the compiler gives you inside instance code, and knowing exactly what they point to solves a large number of output-prediction questions.
The keyword this is a reference to the current object, the one whose method or constructor is running. There are four classic uses. First, to resolve naming conflicts between a parameter and a field: in a constructor Person(String name), writing this.name = name makes it clear the left side is the field. Second, to call another constructor of the same class using this(...), which we call constructor chaining. Third, to pass the current object as an argument to another method, such as registering yourself as a listener. Fourth, to return the current object from a method, which enables fluent chaining like builder.name("x").age(3). It cannot be used in a static context, because static methods run without any object.
The keyword super is a reference to the parent class part of the current object. It also has three uses. To call the parent's constructor with super(...), which must be the first statement. To call an overridden parent method with super.method(), useful when you want to extend rather than replace behaviour. To access a parent field hidden by a child field of the same name, with super.field. Like this, it cannot be used in a static context.
Now the important nuance: super is not a separate object. When you create a Child, there is only one object; the parent's fields and methods live inside that same object. So super merely tells the compiler to look up a name starting from the parent class. Also, this(...) and super(...) cannot both appear in the same constructor, because each must be the first statement.
Walk through the example. Creating new Child() first calls the Child constructor, which begins with super(), so Parent() runs and prints Parent(). Then the rest of the Child constructor runs and prints Child(). Calling show() executes Child.show, which first calls super.show() printing Parent.show, and then prints this.name and super.name. Both classes declare a field called name, so the object holds two separate fields. this.name resolves to Child's value, super.name to Parent's value, so the line prints Child Parent.
Interviewers like to add a twist: what if Parent has no no-argument constructor? Then the compiler complains at the Child constructor because it silently tries to insert super() and finds nothing to call. The fix is to call super(args) explicitly. Another twist: what does this refer to inside a Parent method when the object is a Child? The this reference is the Child object at run time, so overridden methods are called on it, which is the basis for the template method pattern.
class Parent {
String name = "Parent";
Parent() { System.out.println("Parent()"); }
void show() { System.out.println("Parent.show"); }
}
class Child extends Parent {
String name = "Child";
Child() {
super();
System.out.println("Child()");
}
@Override
void show() {
super.show();
System.out.println(this.name + " " + super.name);
}
}
public class ThisSuperDemo {
public static void main(String[] args) {
new Child().show();
}
}
One object, two name fields; this and super select which one is read.
this, super, constructor-chaining, field-shadowing