Java super Keyword
Reference the parent class in Java with super — calling parent constructors and overridden methods.
super is this's counterpart for the parent class. Where this is "the current object", super is "the current object, viewed as its superclass." It shows up in three places:
super(args)inside a constructor — call a parent constructor.super.method(args)inside an instance method — call the parent's version of an overridden method.super.fieldinside an instance method — read a parent field that the subclass shadows.
The first is overwhelmingly the most common.
super(...) — calling a parent constructor
Every subclass constructor must start by calling some parent constructor. If you don't write one, Java inserts super(); as the first line — a call to the parent's no-arg constructor:
public class Animal {
String name;
public Animal() { name = "(unnamed)"; } // no-arg
}
public class Cat extends Animal {
public Cat() {
// super(); ← inserted by the compiler
}
}When the parent has no no-arg constructor, you have to call one explicitly:
public class Animal {
String name;
public Animal(String name) { this.name = name; } // no no-arg constructor
}
public class Cat extends Animal {
public Cat(String name) {
super(name); // required — there is no Animal()
}
}Rules for super(...):
- It must be the first statement in the constructor body.
- A constructor may either chain to another constructor on the same class with
this(...)or call a parent withsuper(...)— not both. - The arguments must match an existing parent constructor.
Why the "first statement" rule?
The JVM has to fully construct the parent's portion of the object before any subclass code runs. That includes initializing final fields the parent declares. Letting subclass code run first would mean writing into those fields before they've been assigned their values.
super.method(args) — calling the parent's version
Inside an instance method, super.method(...) calls the parent's version of method, even if the current class has overridden it:
public class Animal {
String speak() { return "(some noise)"; }
}
public class Cat extends Animal {
@Override
String speak() {
return super.speak() + " — actually, meow";
// ^^^^^^^^^^^^^ calls Animal.speak(), not Cat.speak()
}
}
new Cat().speak(); // "(some noise) — actually, meow"Without super., a plain speak() inside Cat.speak would call itself and recurse forever.
The classic pattern is to extend the parent's behavior rather than replace it:
@Override
void onSave() {
super.onSave(); // run parent's save logic first
// then add subclass-specific behavior
}super.method(...) cannot reach two levels up — there is no super.super.method() in Java. If your class extends a class that extends another, you can call your immediate parent's method, not your grandparent's.
super.field — reaching past a shadowed field
If a subclass declares a field with the same name as a parent's field, the subclass's field shadows the parent's:
public class A {
String label = "A's label";
}
public class B extends A {
String label = "B's label";
void show() {
System.out.println(label); // B's label
System.out.println(super.label); // A's label
System.out.println(this.label); // B's label
}
}This is almost always a bad design — having two fields with the same name on a parent-child pair is confusing — but the language gives you super.field to disambiguate when it happens. The cleaner fix is to rename one of the fields.
Note that fields are not polymorphic. Unlike overridden methods, field access is decided at compile time based on the declared type of the reference. The polymorphism chapter goes into why.
super and static
super only exists in instance contexts, like this. You can't write super in a static method or initializer — there's no current object, so there's no parent view of it either. To call a static method declared on the parent, qualify it with the parent's class name:
public class A { static void hi() { System.out.println("hi"); } }
public class B extends A {
static void demo() {
A.hi(); // ok — call by class name
// super.hi(); // ERROR — super in a static context
}
}A subclass can also declare a static method with the same name as a parent's static method — this is called method hiding, not overriding, and it follows compile-time rules. It's covered briefly in the method overriding chapter.
Chains of super
Each super(...) call activates the next layer of the inheritance chain. Tracing what runs for a deeply nested subclass:
new SiameseCat("Lulu")
→ SiameseCat(String)
→ super("Lulu") — Cat(String)
→ super("Lulu") — Animal(String)
→ super() — Object()
→ Animal body runs
→ Cat body runs
→ SiameseCat body runsInitialization always proceeds from the most-distant ancestor down to the current class. By the time SiameseCat's body runs, every parent field is fully initialized.
A worked example
What's next
super is the bridge to the parent class, but the bigger idea it enables is polymorphism — the ability to call a method on a parent-typed reference and have it dispatch to the right subclass implementation at runtime. That's the next chapter. Continue to Java polymorphism.
Practice
Inside a constructor, when does the compiler implicitly insert super();?