Course topics

By WebNest Studio Engineering Team

Java - Core Tutorial

super Keyword

super is a reference used inside a subclass to explicitly refer to its immediate superclass — its fields, its methods, or its constructors. It plays a role parallel to this, except this points to the current object while super points specifically to the parent class's part of that same object.

Why it matters

A subclass object contains a superclass part that must be constructed first, and super is how you reach it. It explains the compile error you get when a parent has no no-argument constructor, and it lets an overriding method add to the parent's behaviour instead of replacing it completely.

Watch: Demystifying the super Keyword in Java | Constructors, Methods & Variables Explained

Using an Animal parent and a Dog child, this video shows super() calling the parent constructor as the first line, super.method() running the parent's version of an overridden method, super.variable reaching a hidden parent field, and how constructor chaining works, with common mistakes and interview questions.

Watch on YouTube

super(...) — Calling the Superclass Constructor

super(...) invokes a constructor of the immediate superclass, and if used, it must be the first statement inside the subclass constructor — the compiler rejects any code before it, for the same reason this(...) must come first. If a subclass constructor does not explicitly call super(...), Java automatically inserts a call to the superclass's no-argument constructor as the first statement. If the superclass has no no-argument constructor available, the subclass is then required to call super(...) explicitly with matching arguments, or the code fails to compile.

super.field and super.method() — Accessing Hidden or Overridden Members

super.fieldName accesses a field defined in the superclass, which is useful when a subclass declares a field with the same name (field hiding). super.methodName() calls the superclass's version of a method even when the subclass has overridden that method — this is commonly used inside an overriding method to extend, rather than completely replace, the parent's behavior.

  • super(...) must be the first statement in a constructor, exactly like this(...).
  • A constructor cannot contain both this(...) and super(...) — only one first statement is allowed.
  • super.method() is often used inside an override to run the parent behavior and then add subclass-specific logic.

super.variable and Field Hiding

Methods are overridden, but fields are not. If Dog declares a field type and Animal already has one with the same name, a Dog object holds two separate fields. Inside Dog, plain type and this.type mean the dog's field, and super.type reaches the one declared in Animal. Which field you get depends on the declared type of the reference, not the real object: through an Animal variable you see Animal's field even when the object is a Dog. That is the opposite of how overridden methods behave, and it is why field hiding is best avoided in real code. Give the field a different name, or make it private and expose it through a method.

Constructor Chaining Up the Hierarchy

Every constructor starts by running a constructor of its parent, either the one you name with super(...) or, when you write nothing, the parent's no-argument constructor that the compiler inserts for you. That parent constructor in turn calls its own parent, all the way up to Object. The result is that constructors run from the top of the hierarchy down: for Puppy extends Dog extends Animal, creating a Puppy prints Animal(), then Dog(), then Puppy(). This order guarantees that the parent's fields are set up before the child's constructor body can use them.

What super Cannot Do

  • It cannot be used in a static method or static block. There is no current object there, so the compiler reports non-static variable super cannot be referenced from a static context.
  • It cannot skip a level: super.super.method() is not valid Java. A class can only reach its immediate parent; if the grandparent's behaviour is needed, the parent has to expose it.
  • It cannot reach private members of the parent. super.secret fails to compile when secret is private, just as it would without super.

Examples

super() for construction and super.method() to extend overridden behavior

Java
class Animal {
    String name;

    Animal(String name) {
        this.name = name;
    }

    void makeSound() {
        System.out.println(name + " makes a generic animal sound");
    }
}

class Dog extends Animal {
    Dog(String name) {
        super(name); // must be first statement
    }

    @Override
    void makeSound() {
        super.makeSound(); // run the parent version first
        System.out.println(name + " barks");
    }

    public static void main(String[] args) {
        Dog d = new Dog("Rex");
        d.makeSound();
    }
}
Output
Rex makes a generic animal sound
Rex barks

All three uses together: super(), super.variable and super.method()

Java
public class SuperDemo {
    public static void main(String[] args) {
        Dog d = new Dog("Rex");
        System.out.println("---");
        d.describe();
        System.out.println("---");
        d.makeSound();
    }
}

class Animal {
    String name;
    String type = "animal";

    Animal(String name) {
        this.name = name;
        System.out.println("Animal constructor: " + name);
    }

    void makeSound() {
        System.out.println(name + " makes a sound");
    }
}

class Dog extends Animal {
    String type = "dog";          // hides Animal.type

    Dog(String name) {
        super(name);              // runs Animal(String) first
        System.out.println("Dog constructor: " + name);
    }

    void describe() {
        System.out.println("type       = " + type);
        System.out.println("this.type  = " + this.type);
        System.out.println("super.type = " + super.type);
        Animal asAnimal = this;
        System.out.println("((Animal) this).type = " + asAnimal.type);
    }

    @Override
    void makeSound() {
        super.makeSound();        // parent's version first
        System.out.println(name + " barks");
    }
}
Output
Animal constructor: Rex
Dog constructor: Rex
---
type       = dog
this.type  = dog
super.type = animal
((Animal) this).type = animal
---
Rex makes a sound
Rex barks

Constructor chaining across three levels

Java
public class Chain {
    public static void main(String[] args) {
        new Puppy();
    }
}

class Animal {
    Animal() { System.out.println("1. Animal()"); }
}

class Dog extends Animal {
    Dog() { System.out.println("2. Dog()"); }          // compiler inserts super();
}

class Puppy extends Dog {
    Puppy() {
        super();                                        // explicit, same effect
        System.out.println("3. Puppy()");
    }
}
Output
1. Animal()
2. Dog()
3. Puppy()

The compile errors you will meet (javac 17)

Java
// 1. Parent has no no-argument constructor, child does not call super(...)
class Animal {
    String name;
    Animal(String name) { this.name = name; }
}
class Dog extends Animal {
    Dog() {
        System.out.println("creating a dog");
    }
}

// 2. A statement before super(...)
class Cat extends Animal {
    Cat(String name) {
        if (name.isBlank()) throw new IllegalArgumentException("name required");
        super(name);
    }
}

// 3. super inside a static method
class Bird extends Animal {
    Bird() { super("bird"); }
    static void test() {
        super.toString();
    }
}
Output
1. error: constructor Animal in class Animal cannot be applied to given types;
       Dog() {
             ^
     required: String
     found:    no arguments
     reason: actual and formal argument lists differ in length

2. error: call to super must be first statement in constructor
           super(name);
                ^

3. error: non-static variable super cannot be referenced from a static context
           super.toString();
           ^

Common Mistakes

  • Placing statements before super(...) in a subclass constructor, which is a compile-time error.
  • Forgetting that the compiler inserts an implicit no-argument super() call when none is written, which fails to compile if the superclass has no no-argument constructor.
  • Trying to write both this(...) and super(...) in the same constructor — only one of them may occupy the required first-statement position.
  • Using "super" inside a static method, where it has no meaning since there is no current object.
  • Expecting fields to behave like overridden methods. A hidden field is chosen by the reference type, so an Animal variable shows Animal's value even for a Dog.
  • Writing super.super.method() to reach a grandparent; Java only allows access to the immediate parent.
  • Forgetting super.method() inside an override that should extend the parent, so the parent's work (logging, validation, cleanup) silently stops happening.

Exercise

Complete Manager so that its constructor passes the name to Employee, and its describe() reuses the parent's version and adds (manager).

Expected output: Ravi (manager)

Java · starter code
class Employee {
    private final String name;

    Employee(String name) {
        this.name = name;
    }

    String describe() {
        return name;
    }
}

class Manager extends Employee {

    Manager(String name) {
        // TODO: pass the name to the Employee constructor
    }

    // TODO: override describe() to return the parent's text plus " (manager)"
}

public class ManagerDemo {
    public static void main(String[] args) {
        System.out.println(new Manager("Ravi").describe());
    }
}
Show hints
  • super(name); calls the superclass constructor and must be the first statement.
  • name is private in Employee, so use super.describe() to get it.
Show solution
Java · solution
class Employee {
    private final String name;

    Employee(String name) {
        this.name = name;
    }

    String describe() {
        return name;
    }
}

class Manager extends Employee {

    Manager(String name) {
        super(name);
    }

    @Override
    String describe() {
        return super.describe() + " (manager)";
    }
}

public class ManagerDemo {
    public static void main(String[] args) {
        System.out.println(new Manager("Ravi").describe()); // Ravi (manager)
    }
}

Quick quiz

1. A subclass constructor does not call super(...) or this(...). What does the compiler do?

  • A. Nothing
  • B. Inserts a call to super() with no arguments
  • C. Reports an error in every case
  • D. Calls the subclass constructor twice
Show answer

B. The compiler adds super() as the first statement, so the superclass part is always constructed first.

2. Parent declares only Parent(int x). Child extends Parent has the constructor Child() { }. What happens?

  • A. It compiles and x is 0
  • B. It does not compile
  • C. It throws at runtime
  • D. It calls Parent(0) automatically
Show answer

B. The compiler inserts super(), but Parent has no no-argument constructor. Child must call super(someValue) explicitly.

3. Can one constructor contain both this(...) and super(...)?

  • A. Yes, in any order
  • B. Yes, if super comes first
  • C. No, each must be the first statement, so only one is possible
  • D. Only in abstract classes
Show answer

C. Both calls have to be the first statement of the constructor, so a constructor can use one or the other, not both.

Interview questions

In what order do constructors run when you create a subclass object?

Show answer

From the top of the hierarchy downwards. The subclass constructor is entered first, but its first action is to call the superclass constructor, which in turn calls its own parent, up to Object. Each constructor body then finishes in order from the topmost class down to the subclass. So the parent part of the object is always fully constructed before the child's constructor body runs.

What can super be used for?

Show answer

super(...) calls a superclass constructor. super.method() calls the superclass version of a method the subclass has overridden. super.field reads a superclass field that the subclass has hidden with a field of the same name. It cannot be used in a static context, and it cannot be chained as super.super.

Key Points to Remember

  • super(...) calls a superclass constructor and must be the first statement in the subclass constructor.
  • If omitted, Java implicitly calls the superclass's no-argument constructor first.
  • super.field and super.method() access the superclass's version of a hidden field or overridden method.
  • Constructors run from the top of the hierarchy down: Animal, then Dog, then Puppy.
  • Fields are hidden, not overridden: the reference type decides which one you read.
  • super is unavailable in static code, cannot skip a level, and cannot reach private members.

Practice in the playground

Write and run your own code for this topic, or start from the exercise or an example. Runs plain Java 17. Frameworks such as Spring, and databases, are not available here. Your code for each topic is kept in this browser.

Run the examples

Change an input, predict the result, then compare it with the output. Explain why the result changes.

WebNest Studio

Written by

WebNest Studio Engineering Team

Practical lessons from developers working with Java, Python, React, databases and production systems.

Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering