Learn Java

this vs super in Java, with Examples

By Updated 8 min read

In Java, this is a reference to the current object, the one whose method or constructor is running, and superis that same object seen through its parent class, which you use to call the parent's version of a method or run the parent's constructor. Below, this.field, this(), super.method() and super() run side by side in programs you can step through, followed by the rules javac enforces and two tables that compare them.

Main.java
1public class Main {
2 public static void main(String[] args) {
3 Dog rex = new Dog("Rex");
4 System.out.println(rex.describe());
5 }
6}
7
8class Animal {
9 String name;
10
11 Animal(String name) {
12 this.name = name;
13 }
14
15 String describe() {
16 return name + " is an animal";
17 }
18}
19
20class Dog extends Animal {
21 Dog(String name) {
22 super(name);
23 }
24
25 @Override
26 String describe() {
27 return super.describe() + " and a dog";
28 }
29}
Prints
›Rex is an animal and a dog

It prints Rex is an animal and a dog, and each line with this or super does one job. In Dog's constructor, super(name) runs Animal's constructor, so the part of the dog it inherits is set up first. Inside that constructor, this.name = name stores the parameter in the name field of the object being built; this is the dog, even though the code is in Animal. In Dog's describe(), super.describe() runs Animal's version of the method, and the dog adds " and a dog" to what it returns. Step through it and watch the memory view: there is one Dog object the whole time, and this and super both lead to it.

this vs super: the difference#

this and super refer to the same object. The difference is where Java looks for the member you name: this.sound() runs the object's own version, while super.sound() runs the version in the parent of the class you are writing, skipping any override.

thissuper
What it refers toThe current object.The same object, seen as an instance of its parent class.
With a dot, on a methodthis.sound() runs the object's own version, which may be an override in a subclass.super.sound() runs the parent class's version, skipping the override in the current class.
With a dot, on a fieldthis.name is this object's name field. It tells the field apart from a parameter called name.super.name is the parent class's field, which only matters if the current class declares its own name.
With parenthesesthis(...) calls another constructor of the same class.super(...) calls a constructor of the parent class.
On its ownA value you can store, pass or return: return this;Not allowed. super cannot stand alone, so return super; does not compile.
In a static methodNot allowed: there is no current object.Not allowed, for the same reason.
this and super side by side.

The this keyword: fields, methods and the current object#

this is a reference to the object a method or constructor is running on: during rex.describe(), this is the object rex points at. Its most common job is telling a field apart from a parameter with the same name, in a constructor or a setter.

Main.java
1public class Main {
2 public static void main(String[] args) {
3 Account acc = new Account("Ada", 100);
4 acc.deposit(50);
5 acc.setOwner("Ada Lovelace");
6 acc.printSummary();
7 }
8}
9
10class Account {
11 String owner;
12 int balance;
13
14 Account(String owner, int balance) {
15 this.owner = owner;
16 this.balance = balance;
17 }
18
19 void setOwner(String owner) {
20 this.owner = owner;
21 }
22
23 void deposit(int amount) {
24 balance = balance + amount;
25 this.printSummary();
26 }
27
28 void printSummary() {
29 System.out.println(owner + ": " + balance);
30 }
31}
Prints
›Ada: 150
›Ada Lovelace: 150

It prints Ada: 150, then Ada Lovelace: 150. In the constructor and in setOwner, the parameter has the same name as the field, and the closer name wins, so a bare owner means the parameter. this.owner means the owner field of this object, which makes this.owner = owner copy the parameter into the field. In deposit there is no clash, so balance alone already means the field. this.printSummary() calls another method on the same object; plain printSummary() does exactly the same, because Java puts the this. in for you.

Forgetting this. in a setter
If setOwner said owner = owner;, both names would mean the parameter, and the parameter would be copied onto itself. The program still compiles, javac gives no warning, and the field keeps its old value: the second line would still say Ada: 150.

Passing this and returning this#

this is an ordinary reference, so a method can hand it to another object or return it. Returning this lets calls chain, one after another on the same object; StringBuilder's append works this way.

Main.java
1import java.util.ArrayList;
2import java.util.List;
3
4public class Main {
5 public static void main(String[] args) {
6 Order order = new Order();
7 order.add("tea").add("cake").add("juice");
8
9 Kitchen kitchen = new Kitchen();
10 order.sendTo(kitchen);
11 }
12}
13
14class Order {
15 List<String> items = new ArrayList<>();
16
17 Order add(String item) {
18 items.add(item);
19 return this;
20 }
21
22 void sendTo(Kitchen kitchen) {
23 kitchen.cook(this);
24 }
25}
26
27class Kitchen {
28 void cook(Order order) {
29 System.out.println("Cooking " + order.items);
30 }
31}
Prints
›Cooking [tea, cake, juice]

It prints Cooking [tea, cake, juice]. Each add puts an item in the list and returns this, the same order, so the next .add(...) in the chain runs on it. sendTo passes thisto the kitchen, which reads the order's items through its own parameter. Step through it: kitchen.cook(this) hands over the very object that order points at, not a copy.

this(): calling another constructor of the same class#

this(...) with parentheses runs another constructor of the same class, so a short constructor can fill in default values and hand the real work to a fuller one.

Main.java
1public class Main {
2 public static void main(String[] args) {
3 Pizza a = new Pizza("large", "olives");
4 Pizza b = new Pizza("small");
5 Pizza c = new Pizza();
6
7 System.out.println(a.size + " with " + a.topping);
8 System.out.println(b.size + " with " + b.topping);
9 System.out.println(c.size + " with " + c.topping);
10 }
11}
12
13class Pizza {
14 String size;
15 String topping;
16
17 Pizza(String size, String topping) {
18 this.size = size;
19 this.topping = topping;
20 }
21
22 Pizza(String size) {
23 this(size, "cheese");
24 }
25
26 Pizza() {
27 this("medium");
28 }
29}
Prints
›large with olives
›small with cheese
›medium with cheese

It prints large with olives, small with cheese and medium with cheese. new Pizza() runs the constructor with no parameters, which hands over with this("medium"); that one hands over with this(size, "cheese"); and only the two-parameter constructor sets the fields, so the setup is written once. Constructors may not hand over to each other in a loop: javac reports recursive constructor invocation. The constructors lesson covers chaining in full.

super.method(): the parent's version of a method#

super.method()runs the parent class's version of a method, on the same object, even when the current class overrides it. That is how an override builds on the method it replaces, as Dog's describe() did at the top of this page. Here one dog calls both versions of sound().

Main.java
1public class Main {
2 public static void main(String[] args) {
3 Dog rex = new Dog();
4 rex.compare();
5 }
6}
7
8class Animal {
9 String sound() {
10 return "...";
11 }
12}
13
14class Dog extends Animal {
15 @Override
16 String sound() {
17 return "Woof";
18 }
19
20 void compare() {
21 System.out.println("this.sound() gives " + this.sound());
22 System.out.println("super.sound() gives " + super.sound());
23 }
24}
Prints
›this.sound() gives Woof
›super.sound() gives ...

It prints this.sound() gives Woof, then super.sound() gives .... Step through it: the narration says both calls run on the Dog object, yet the first jumps into Dog's sound() and the second into Animal's. super is not a second, hidden Animal object inside the dog. There is one object, and super only changes where Java looks for the method: in the parent class, past the override.

Inside an override, super. is also what stops the method calling itself. If Dog's sound() called plain sound(), it would run itself again and again until Java gave up with a StackOverflowError. super always starts at the direct parent class, and Java has no super.super for skipping a level. Overriding itself is explained in method overloading vs overriding.

Key idea

There is only one object. this and super are two ways of looking up its members: this from the object's own class, super from the parent of the class the code is written in.

super(): running the parent class's constructor#

super(...) with parentheses runs a constructor of the parent class, so the part of the object the subclass inherits is set up first, with the values it needs. In the first program, Dog's constructor called super(name) because Animal's only constructor takes a name.

If a constructor contains neither this(...) nor super(...), Java inserts super()at its start: a call to the parent's constructor that takes no arguments. That only works if the parent has one. Here Animal has only Animal(String name), and Dog's constructor does not call it:

Main.java (does not compile)
read along
1public class Main {
2 public static void main(String[] args) {
3 Dog rex = new Dog("Husky");
4 System.out.println(rex.breed);
5 }
6}
7
8class Animal {
9 String name;
10
11 Animal(String name) {
12 this.name = name;
13 }
14}
15
16class Dog extends Animal {
17 String breed;
18
19 Dog(String breed) {
20 this.breed = breed;
21 }
22}
Output
Main.java:19: error: constructor Animal in class Animal cannot be applied to given types;
    Dog(String breed) {
                      ^
  required: String
  found:    no arguments
  reason: actual and formal argument lists differ in length
1 error

javac points at the opening brace of Dog's constructor, where it tried to insert super(): Animal's constructor needs a String (required: String), and the inserted call has nothing to give it (found: no arguments). The fix is to call the parent's constructor yourself: give Dog a name parameter as well, and pass it on with super(name). A subclass with no constructor at all gets the same error, because the default constructor Java writes for it also calls super().

In what order do constructors run?#

The parent's constructor finishes first: Java runs it before the statements that follow super(...) in the subclass constructor, so an object is built from the top of the family down. That holds whether you write super(...) yourself or Java inserts it, and this program has both, plus a this(...).

Main.java
1public class Main {
2 public static void main(String[] args) {
3 Puppy p = new Puppy();
4 System.out.println("Done: " + p.name + ", " + p.months + " months");
5 }
6}
7
8class Animal {
9 Animal() {
10 System.out.println("Animal constructor");
11 }
12}
13
14class Dog extends Animal {
15 String name;
16
17 Dog(String name) {
18 System.out.println("Dog constructor");
19 this.name = name;
20 }
21}
22
23class Puppy extends Dog {
24 int months;
25
26 Puppy() {
27 this(3);
28 System.out.println("Puppy() constructor");
29 }
30
31 Puppy(int months) {
32 super("Rex");
33 System.out.println("Puppy(int) constructor");
34 this.months = months;
35 }
36}
Prints
›Animal constructor
›Dog constructor
›Puppy(int) constructor
›Puppy() constructor
›Done: Rex, 3 months

It prints Animal constructor, Dog constructor, Puppy(int) constructor, Puppy() constructor and Done: Rex, 3 months. new Puppy() starts in Puppy(), which hands over with this(3) before printing anything. Puppy(int) calls super("Rex"), and Dog(String), which has neither call, gets an inserted super() that runs Animal(). Each constructor prints only after the one it called has finished, so the most general class prints first. Step through it and watch four constructors start before the first line appears.

Key idea

Every chain of constructors ends with a call to the parent class, so the parent's part of an object is set up before the subclass's code uses it.

this() vs super(), and can a constructor call both?#

this() calls another constructor of the same class and super() calls a constructor of the parent class. A constructor may contain at most one of them, so it either hands over within its own class or calls up to the parent, never both.

this(...)super(...)
RunsAnother constructor of the same class.A constructor of the parent class.
Typical jobFill in default values, then hand over to a fuller constructor.Give the parent class the values it needs to set up its part of the object.
If you write neitherNothing is inserted.Java inserts super(), a call to the parent's no-argument constructor.
The error you meetrecursive constructor invocation, when constructors hand over to each other in a loop.constructor ... cannot be applied to given types, when the parent's constructor needs arguments you did not pass.
this() and super() side by side. Both may appear only inside a constructor, at most once.

You never need both. The constructor that this(...) hands over to calls super(...) itself, written or inserted, so the parent part is still built, exactly once. A constructor that contains both does not compile: javac reports redundant explicit constructor invocation.

Statements before this() or super() since Java 25#

Until Java 25, this(...) or super(...)had to be the very first statement of a constructor. Java 25 relaxed that rule with a feature called flexible constructor bodies: statements may now come before the call, as long as they do not use the object being built. They can check or adjust the parameters and work out values in local variables, but they cannot read the object's fields or call its methods. Those statements run before the parent's constructor, while the inherited part of the object is not set up yet, which is why the object is off limits to them.

Main.java
1public class Main {
2 public static void main(String[] args) {
3 Reading r = new FahrenheitReading(212);
4 System.out.println(r.celsius + " degrees Celsius");
5 }
6}
7
8class Reading {
9 double celsius;
10
11 Reading(double celsius) {
12 this.celsius = celsius;
13 }
14}
15
16class FahrenheitReading extends Reading {
17 FahrenheitReading(double fahrenheit) {
18 double celsius = (fahrenheit - 32) * 5 / 9;
19 super(celsius);
20 }
21}
Prints
›100.0 degrees Celsius

It prints 100.0 degrees Celsius. The constructor works out the Celsius value from its parameter before handing it to Reading's constructor, and touches nothing of the object until super(celsius) has run. Most Java code you will read still puts the call first; the inheritance lesson shows another example of each style.

Can you use this or super in a static method?#

No: a static method runs without any object, so there is no current object for this or super to refer to. main is static, which is why this program fails:

Main.java (does not compile)
read along
1public class Main {
2 String name = "Ada";
3
4 public static void main(String[] args) {
5 System.out.println(this.name);
6 }
7}
Output
Main.java:5: error: non-static variable this cannot be referenced from a static context
        System.out.println(this.name);
                           ^
1 error

super.toString() in the same place gets the same message, with super in place of this. To use an object from a static method, create one with new and call its methods through a variable, as every main on this page does. The this keyword and object references lesson goes further into what this holds.

Questions people ask#

What is the difference between this and super in Java?
this refers to the current object, and super refers to the same object seen through its parent class. this.sound() runs the object's own version of a method while super.sound() runs the parent class's version, and this(...) calls a constructor of the same class while super(...) calls one of the parent class.
What is the difference between super and super()?
super with a dot, as in super.sound(), reaches a method or field of the parent class from inside an instance method or constructor. super() with parentheses calls a constructor of the parent class, and it can only appear inside a constructor.
What is the difference between this and this() in Java?
this is a reference to the current object, which you can use in any instance method or constructor, and store, pass or return like any other reference. this() calls another constructor of the same class, and it can only appear inside a constructor.
What is the difference between this() and super()?
this() calls another constructor of the same class, and super() calls a constructor of the parent class. A constructor can contain only one of the two, and if it has neither, Java inserts super() at its start.
What is super() used for in Java?
super() runs the parent class's constructor so that the part of the object the subclass inherits is set up first, and super(name) passes that constructor the values it needs. If you leave it out, Java inserts a call to the parent's no-argument constructor.
Can you use this or super in a static method?
No. A static method does not run on any object, so there is nothing for this or super to refer to, and javac stops with non-static variable this cannot be referenced from a static context.

Further reading#

Learn it step by step

These lessons teach the topic from the start, with more examples and questions to check yourself.

All guides

Spotted a mistake, or a part that did not make sense? Report it by email