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.
public class Main { public static void main(String[] args) { Dog rex = new Dog("Rex"); System.out.println(rex.describe()); }} class Animal { String name; Animal(String name) { this.name = name; } String describe() { return name + " is an animal"; }} class Dog extends Animal { Dog(String name) { super(name); } @Override String describe() { return super.describe() + " 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.
| this | super | |
|---|---|---|
| What it refers to | The current object. | The same object, seen as an instance of its parent class. |
| With a dot, on a method | this.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 field | this.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 parentheses | this(...) calls another constructor of the same class. | super(...) calls a constructor of the parent class. |
| On its own | A value you can store, pass or return: return this; | Not allowed. super cannot stand alone, so return super; does not compile. |
| In a static method | Not allowed: there is no current object. | Not allowed, for the same reason. |
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.
public class Main { public static void main(String[] args) { Account acc = new Account("Ada", 100); acc.deposit(50); acc.setOwner("Ada Lovelace"); acc.printSummary(); }} class Account { String owner; int balance; Account(String owner, int balance) { this.owner = owner; this.balance = balance; } void setOwner(String owner) { this.owner = owner; } void deposit(int amount) { balance = balance + amount; this.printSummary(); } void printSummary() { System.out.println(owner + ": " + balance); }}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.
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.
import java.util.ArrayList;import java.util.List; public class Main { public static void main(String[] args) { Order order = new Order(); order.add("tea").add("cake").add("juice"); Kitchen kitchen = new Kitchen(); order.sendTo(kitchen); }} class Order { List<String> items = new ArrayList<>(); Order add(String item) { items.add(item); return this; } void sendTo(Kitchen kitchen) { kitchen.cook(this); }} class Kitchen { void cook(Order order) { System.out.println("Cooking " + order.items); }}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.
public class Main { public static void main(String[] args) { Pizza a = new Pizza("large", "olives"); Pizza b = new Pizza("small"); Pizza c = new Pizza(); System.out.println(a.size + " with " + a.topping); System.out.println(b.size + " with " + b.topping); System.out.println(c.size + " with " + c.topping); }} class Pizza { String size; String topping; Pizza(String size, String topping) { this.size = size; this.topping = topping; } Pizza(String size) { this(size, "cheese"); } Pizza() { this("medium"); }}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().
public class Main { public static void main(String[] args) { Dog rex = new Dog(); rex.compare(); }} class Animal { String sound() { return "..."; }} class Dog extends Animal { @Override String sound() { return "Woof"; } void compare() { System.out.println("this.sound() gives " + this.sound()); System.out.println("super.sound() gives " + super.sound()); }}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 ideaThere is only one object.
thisandsuperare two ways of looking up its members:thisfrom the object's own class,superfrom 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:
public class Main { public static void main(String[] args) { Dog rex = new Dog("Husky"); System.out.println(rex.breed); }} class Animal { String name; Animal(String name) { this.name = name; }} class Dog extends Animal { String breed; Dog(String breed) { this.breed = breed; }}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 errorjavac 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(...).
public class Main { public static void main(String[] args) { Puppy p = new Puppy(); System.out.println("Done: " + p.name + ", " + p.months + " months"); }} class Animal { Animal() { System.out.println("Animal constructor"); }} class Dog extends Animal { String name; Dog(String name) { System.out.println("Dog constructor"); this.name = name; }} class Puppy extends Dog { int months; Puppy() { this(3); System.out.println("Puppy() constructor"); } Puppy(int months) { super("Rex"); System.out.println("Puppy(int) constructor"); this.months = 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 ideaEvery 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(...) | |
|---|---|---|
| Runs | Another constructor of the same class. | A constructor of the parent class. |
| Typical job | Fill 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 neither | Nothing is inserted. | Java inserts super(), a call to the parent's no-argument constructor. |
| The error you meet | recursive 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. |
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.
public class Main { public static void main(String[] args) { Reading r = new FahrenheitReading(212); System.out.println(r.celsius + " degrees Celsius"); }} class Reading { double celsius; Reading(double celsius) { this.celsius = celsius; }} class FahrenheitReading extends Reading { FahrenheitReading(double fahrenheit) { double celsius = (fahrenheit - 32) * 5 / 9; super(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:
public class Main { String name = "Ada"; public static void main(String[] args) { System.out.println(this.name); }}Main.java:5: error: non-static variable this cannot be referenced from a static context
System.out.println(this.name);
^
1 errorsuper.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?
thisrefers to the current object, andsuperrefers to the same object seen through its parent class.this.sound()runs the object's own version of a method whilesuper.sound()runs the parent class's version, andthis(...)calls a constructor of the same class whilesuper(...)calls one of the parent class.- What is the difference between super and super()?
superwith a dot, as insuper.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?
thisis 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, andsuper()calls a constructor of the parent class. A constructor can contain only one of the two, and if it has neither, Java insertssuper()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, andsuper(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
thisorsuperto refer to, and javac stops withnon-static variable this cannot be referenced from a static context.
Further reading#
- Using the this Keyword, from the dev.java tutorial, with fields and with constructors
- Using the Keyword super, from the dev.java tutorial, with superclass members and subclass constructors
- Constructor Body, section 8.8.7 of the Java Language Specification for Java SE 25, the exact rules for this(...) and super(...)
- JEP 513: Flexible Constructor Bodies, the Java 25 change that allows statements before this(...) and super(...)