Definition
this and super each have three uses.
- this.field: accesses the current class's field, resolving shadowing when a parameter has the same name.
- this.method(): calls the current class's method. Inside an overridden method,
this.method()calls the current version (careful: can cause infinite recursion). - this(args): calls another constructor in the same class (constructor chaining). Must be the first statement.
- super.field: accesses the parent class's field when shadowed by the child.
- super.method(): calls the parent's version of an overridden method (
super.withdraw(amount)reuses parent logic). - super(args): calls the parent's constructor to initialize inherited state. Must be the first statement.
- You cannot use both
this()andsuper()in the same constructor. If you write neither, Java implicitly insertssuper().
this is the current employee at National Bank of India saying my desk, my tools, my procedures. super is the employee saying my manager's desk, my manager's tools, my manager's procedures. When SavingsAccount overrides withdraw(), calling super.withdraw(amount) says first do what Account (my parent) does, then I will add my extra check.
Understanding the Concepts
What is the difference between this and super?
Both keywords have three uses: accessing fields, calling methods, and calling constructors.
How do this and super resolve field shadowing?
package com.bank.core;
public class Account {
protected String name = "Account";
}
public class SavingsAccount extends Account {
private String name = "SavingsAccount"; // shadows parent field
public void printNames() {
System.out.println(this.name); // "SavingsAccount" (this class)
System.out.println(super.name); // "Account" (parent class)
}
}
How do this and super work with method calls?
public class Account {
public void withdraw(java.math.BigDecimal amount) {
if (balance.compareTo(amount) < 0) throw new IllegalStateException("Insufficient funds");
balance = balance.subtract(amount);
}
}
public class SavingsAccount extends Account {
private static final java.math.BigDecimal MIN_BALANCE = new java.math.BigDecimal("1000");
@Override
public void withdraw(java.math.BigDecimal amount) {
if (balance.subtract(amount).compareTo(MIN_BALANCE) < 0) {
throw new IllegalStateException("Would go below Rs." + MIN_BALANCE);
}
super.withdraw(amount); // call parent's withdraw: does the actual debit
// this.withdraw(amount) would cause INFINITE RECURSION.
}
}
How do this() and super() work with constructors?
public class Account {
private final String accountId;
private java.math.BigDecimal balance;
private final String holderName;
public Account(String accountId, String holderName, java.math.BigDecimal balance) {
this.accountId = accountId;
this.holderName = holderName;
this.balance = balance;
}
public Account(String accountId, String holderName) {
this(accountId, holderName, java.math.BigDecimal.ZERO); // this() chains to primary
}
}
public class SavingsAccount extends Account {
private final java.math.BigDecimal interestRate;
public SavingsAccount(String id, String name, java.math.BigDecimal bal, java.math.BigDecimal rate) {
super(id, name, bal); // super() calls Account's constructor
this.interestRate = rate;
}
public SavingsAccount(String id, String name) {
this(id, name, java.math.BigDecimal.ZERO, new java.math.BigDecimal("0.04")); // this() chains
}
// Cannot use both this() and super() in same constructor:
// public SavingsAccount(String id) {
// super(id, "Unknown", BigDecimal.ZERO); // first statement
// this(id, "Unknown"); // compile error: second constructor call not allowed
// }
}
What happens when you write no constructor call?
Java inserts super() implicitly, calling the parent's no-arg constructor.
public class CurrentAccount extends Account {
public CurrentAccount() {
// Java inserts: super(); -> calls Account's no-arg constructor
// If Account has no no-arg constructor -> compile error
}
}
How is this used as a reference?
public class Trade {
private Account account;
public void associateWith(Account account) {
this.account = account; // this.account = field. account = parameter.
account.addTrade(this); // this = current Trade object passed to Account
}
}
How do this and super compare?
| Aspect | this | super |
|--------|------|-------|
| Refers to | Current object instance | Parent class |
| Field access | this.balance (current class) | super.balance (parent class) |
| Method call | this.method() (current version) | super.method() (parent version) |
| Constructor | this(args) (same class) | super(args) (parent class) |
| Position | First statement in constructor | First statement in constructor |
What are common mistakes?
The most common mistake is calling this.method() inside an overridden method, causing infinite recursion.
// WRONG: infinite recursion
public class CurrentAccount extends Account {
@Override public void withdraw(java.math.BigDecimal amount) {
this.withdraw(amount); // calls THIS method again, infinite loop
}
}
// CORRECT: call parent's version
public class CurrentAccount extends Account {
@Override public void withdraw(java.math.BigDecimal amount) {
super.withdraw(amount); // calls Account.withdraw()
}
}
What should a senior engineer know?
- In records, the canonical constructor is called implicitly. There is no explicit super() because records extend Record.
- In Spring, constructor injection uses this pattern: the constructor receives dependencies and assigns them to fields using this.field = parameter.
- The this keyword is also used in the Builder pattern to enable fluent method chaining: return this;
Visual Overview
this vs super
──────────────────────────────────────────
this super
┌──────────────────┐ ┌──────────────────┐
│ Current object │ │ Parent class │
│ │ │ │
│ this.balance │ │ super.balance │
│ (my field) │ │ (parent field) │
│ │ │ │
│ this.withdraw() │ │ super.withdraw() │
│ (my version) │ │ (parent version) │
│ │ │ │
│ this(args) │ │ super(args) │
│ (my constructor) │ │ (parent constr.) │
└──────────────────┘ └──────────────────┘
Constructor chaining:
SavingsAccount(id, name)
│ this(id, name, ZERO, 0.04)
▼
SavingsAccount(id, name, bal, rate)
│ super(id, name, bal)
▼
Account(id, name, bal)
Key Takeaway
this refers to the current object instance, used for three things: accessing the current class's fields when shadowed by parameters (this.balance = balance), calling another constructor in the same class (this(args) for constructor chaining), and passing the current object as a reference (return this). super refers to the parent class, also with three uses: accessing the parent's field when shadowed (super.name), calling the parent's version of an overridden method (super.withdraw(amount) to reuse parent logic), and calling the parent's constructor (super(args) to initialize parent state).
In Pankaj's banking system at National Bank of India, super.withdraw(amount) is the most practical use: SavingsAccount.withdraw() first checks minimum balance (child's extra validation), then calls super.withdraw(amount) which does the actual debit and logging (parent's logic). Constructor chaining is the second most practical: this(accountId, holderName, ZERO, 0.04) lets the two-argument constructor delegate to the four-argument constructor, which delegates to super(...).
Remember one sentence: this refers to the current object and super refers to the parent class, both can access fields, methods, and constructors, and in constructors this() or super() must be the first statement but never both.
---