super Keyword

Su Suriya Ravichandran Updated 14 Nov 2026
7 min read ·Lesson 55 of 133

The super keyword refers to the superclass part of the current object. A subclass uses it in two ways: super(...) calls a superclass constructor, and super.member reaches a superclass method or field, most often to call the parent's version of a method the subclass has overridden. super is what lets a subclass build on its parent rather than replacing it.

Calling a Superclass Constructor: super(...)

When an object is created, every class in its hierarchy initializes its own part, starting from the top. A subclass constructor chooses which parent constructor runs by calling super(...):

public class Person {
    private final String name;
    private final int age;

    public Person(String name, int age) {
        if (age < 0) throw new IllegalArgumentException("age cannot be negative");
        this.name = name;
        this.age = age;
    }

    public String getName() { return name; }
    public int getAge() { return age; }
}

public class Student extends Person {
    private final String rollNumber;

    public Student(String name, int age, String rollNumber) {
        super(name, age);                 // initialize the Person part
        this.rollNumber = rollNumber;     // then the Student part
    }
}

Person's fields are private, so Student cannot assign them directly. It passes the values to Person's constructor, which also applies Person's validation. Every Student is therefore guaranteed to be a valid Person.

The implicit super()

If a constructor does not call super(...) or this(...), the compiler inserts super(), a call to the parent's no-argument constructor:

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

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

new Dog();

Output:

Animal constructed
Dog constructed

If the parent has no no-argument constructor, the inserted super() fails to compile:

public class Student extends Person {
    public Student(String rollNumber) {
        // implicit super() → error: constructor Person in class Person cannot be applied to given types
    }
}

The fix is an explicit super(...) with the arguments the parent requires.

Rules for super(...)

  • It can appear only in a constructor.
  • A constructor may call super(...) or this(...), but not both. When this(...) delegates to another constructor, that constructor is the one that calls super(...).
  • Up to Java 24, it must be the first statement. From Java 25 (flexible constructor bodies), statements may come before it, provided they do not use the object being constructed. This is useful for validating or transforming arguments first.
// Works on all versions: compute the argument with a static helper
public Student(String name, int age, String rollNumber) {
    super(normalize(name), age);
    this.rollNumber = rollNumber;
}

private static String normalize(String name) {
    return name == null ? "" : name.strip();
}

Construction Order Across a Hierarchy

class A {
    A() { System.out.println("A"); }
}
class B extends A {
    B() { System.out.println("B"); }
}
class C extends B {
    C() { System.out.println("C"); }
}

new C();

Output:

A
B
C

C() calls B(), which calls A(), which calls Object(). The bodies then complete in order from the top down. By the time a subclass constructor body runs, all of its ancestors are fully initialized.

Calling an Overridden Method: super.method()

When a subclass overrides a method, a plain call runs the subclass version. super.method() runs the parent's version instead, which lets the override extend the original behavior rather than duplicate it:

public class Employee {
    protected final double baseSalary;

    public Employee(double baseSalary) { this.baseSalary = baseSalary; }

    public double monthlyPay() {
        return baseSalary / 12;
    }

    public String describe() {
        return "Employee earning " + String.format("%.2f", monthlyPay()) + " per month";
    }
}

public class SalesEmployee extends Employee {
    private final double commission;

    public SalesEmployee(double baseSalary, double commission) {
        super(baseSalary);
        this.commission = commission;
    }

    @Override
    public double monthlyPay() {
        return super.monthlyPay() + commission;      // parent's calculation plus extra
    }

    @Override
    public String describe() {
        return super.describe() + " (includes commission " + commission + ")";
    }
}
Employee e = new SalesEmployee(600_000, 8_000);
System.out.println(e.monthlyPay());
System.out.println(e.describe());

Output:

58000.0
Employee earning 58000.00 per month (includes commission 8000.0)

Trace e.describe():

  1. SalesEmployee.describe() runs and calls super.describe().
  2. Employee.describe() runs and calls monthlyPay(). Because the object is a SalesEmployee, this dispatches to SalesEmployee.monthlyPay(), not Employee's.
  3. SalesEmployee.monthlyPay() calls super.monthlyPay(), giving 50,000, and adds 8,000.
  4. The result flows back up, and SalesEmployee.describe() appends its note.

super.method() selects the parent's implementation for that single call. Calls made from inside the parent's method are still dispatched polymorphically. This is often exactly what you want, but it is important to understand when reading such code.

Without super: accidental recursion

Forgetting super. in an override calls the override itself:

@Override
public double monthlyPay() {
    return monthlyPay() + commission;    // calls itself forever → StackOverflowError
}

super reaches only one level

super.method() refers to the nearest superclass's version, which may itself be inherited from higher up. There is no super.super.method(); a class cannot skip its parent to reach its grandparent. If such access seems necessary, the hierarchy usually needs redesigning.

Accessing Superclass Fields: super.field

If a subclass declares a field with the same name as a field in its parent, the subclass field hides the parent's. super.field reaches the hidden one:

class Parent {
    protected String label = "parent";
}

class Child extends Parent {
    protected String label = "child";

    void show() {
        System.out.println(label);         // child
        System.out.println(this.label);    // child
        System.out.println(super.label);   // parent
    }
}

The object now contains two separate label fields, which is confusing and rarely intended. Avoid declaring fields with the same names as inherited ones; this use of super mostly appears when reading other people's code.

super in Interfaces with Default Methods

When a class implements two interfaces that both provide a default method with the same signature, it must override the method, and can call a specific interface's version with InterfaceName.super.method():

interface Camera {
    default String status() { return "camera ready"; }
}

interface Microphone {
    default String status() { return "mic ready"; }
}

class Webcam implements Camera, Microphone {
    @Override
    public String status() {
        return Camera.super.status() + ", " + Microphone.super.status();
    }
}

System.out.println(new Webcam().status());   // camera ready, mic ready

Without the override, the class would not compile, because Java cannot choose between the two defaults on its own.

super Is Not Available in Static Context

Like this, super refers to the current object, so it cannot be used in static methods:

public static void helper() {
    super.toString();      // compile error: non-static variable super cannot be referenced from a static context
}

this Versus super

thissuper
Refers toThe current object, viewed as its own classThe current object, viewed as its superclass
Constructor callthis(...): another constructor of the same classsuper(...): a constructor of the parent class
Method callthis.m(): dynamic dispatch, may run an overridesuper.m(): the parent's version specifically
Field accessthis.f: this class's fieldsuper.f: the parent's (hidden) field

Practical Example: Logging Shapes

import java.util.List;

public class ShapesDemo {
    static abstract class Shape {
        private final String color;

        Shape(String color) {
            this.color = color;
        }

        abstract double area();

        @Override
        public String toString() {
            return String.format("%s %s with area %.2f",
                    color, getClass().getSimpleName().toLowerCase(), area());
        }
    }

    static class Rectangle extends Shape {
        protected final double width, height;

        Rectangle(String color, double width, double height) {
            super(color);
            this.width = width;
            this.height = height;
        }

        @Override
        double area() { return width * height; }
    }

    static class Square extends Rectangle {
        Square(String color, double side) {
            super(color, side, side);                     // reuse Rectangle's constructor
        }

        @Override
        public String toString() {
            return super.toString() + " (side " + width + ")";   // extend parent's text
        }
    }

    static class Circle extends Shape {
        private final double radius;

        Circle(String color, double radius) {
            super(color);
            this.radius = radius;
        }

        @Override
        double area() { return Math.PI * radius * radius; }
    }

    public static void main(String[] args) {
        List<Shape> shapes = List.of(
            new Rectangle("blue", 4, 2.5),
            new Square("red", 3),
            new Circle("green", 1.5)
        );
        shapes.forEach(System.out::println);
    }
}

Output:

blue rectangle with area 10.00
red square with area 9.00 (side 3.0)
green circle with area 7.07

Every constructor passes the color up to Shape with super(color), so color handling exists in one place. Square reuses all of Rectangle's setup by calling super(color, side, side) and inherits its area() unchanged. Square.toString() calls super.toString(), which is Shape's version (inherited by Rectangle), and appends the side length. Inside that inherited toString, getClass() and area() still resolve to the actual object, which is why it prints "square" and the square's area.

0 Comments

Reviewed before they appear

No comments yet.

Java
Java Introduction Java Features Java Syntax Java Comments Java Statements Java Output Java Variables Java Data Types Java Type Casting Java Operators Java Strings Java Numbers Java Math Java Booleans Java User Input Java Conditions Java If Else Java Switch Java While Loop Java For Loop Java Break Java Continue Java Arrays Java Methods Java Parameters Java Return Values Java Scope Java Recursion Install Java Install JDK Java IDEs Java JDK Java JRE Java JVM Java Compiler Java File Compile Java Run Java JShell Basics Java Packages Java OOP Java Classes Java Objects Class Methods Constructors Constructor Overload this Keyword static Keyword final Keyword Encapsulation Inheritance Polymorphism Abstraction Access Modifiers super Keyword Method Overload Method Override Instanceof Operator Nested Classes Inner Classes Anonymous Classes Enums Records Array Basics Array Length Loop Arrays Multidimensional Arrays Array Copy Array Sorting Array Search ArrayList LinkedList HashSet TreeSet HashMap TreeMap Queue Interface Deque Interface Stack Class Iterator List Interface Set Interface Map Interface Collections Class Comparable Comparator Generics Basics Generic Classes Generic Methods Wildcards String Basics String Length String Methods String Concatenation String Compare String Search String Replace String Split String Format StringBuilder StringBuffer Text Blocks Regular Expressions Number Types Integer Class Float Class Double Class BigInteger BigDecimal Math Class Random Numbers Number Format Date Basics LocalDate LocalTime LocalDateTime ZonedDateTime Date Formatting Date Parsing Period Class Duration Class Java Instant Class Java Exception Basics Java try...catch Java Multiple Catch Blocks Java finally Block Java throw Keyword Java throws Keyword Java Checked Exceptions Java Unchecked Exceptions Java Custom Exceptions Java try-with-resources Java Exception Chaining
Ask about this post
AI Ask about this post

Ask questions about super Keyword and get answers drawn from it.

Signed-in readers only.