🏗️ Classes & Objects · Intermediate

The this keyword in Java

Refers to the current object; disambiguates fields from parameters.

🧩 The mysterybalance = balance; compiles without a single warning — and does absolutely nothing. Every account you open starts at 0 forever. Who stole the money?

"Who am I?"

Inside a constructor or instance method, **this is a reference to the current object** — the one the code is running on. When you call a.deposit(5), inside deposit, this and a point to the same object.

⚠️ The trap

The shadowing trap

When a parameter has the same name as a field, the parameter *shadows* the field: plain balance now means the parameter. So balance = balance assigns the parameter to itself, and the field stays 0.

class Account {
    int balance;
    Account(int balance) {
        balance = balance; // no effect!
    }
}

Setting the field

✗ Shadowed
Account(int balance) {
    balance = balance;
}

Both names mean the parameter.

✓ Correct
Account(int balance) {
    this.balance = balance;
}

this.balance is the field; plain balance is the parameter.

return this

A method can **return this** — the very same object — so the caller can immediately call another method on it. That's *method chaining*.

class Counter {
    int n;
    Counter add(int k) {
        n += k;
        return this;
    }
}
🔮 Predict it

Chain reaction

What does this print?

class Cart {
    int items;
    Cart add(int n) {
        items += n; return this;
    }
}
void main() {
    var c = new Cart().add(3).add(4);
    System.out.println(c.items);
}
  1. 4
  2. 7
  3. 3
Show the answer

7. add(3) returns the same cart, so add(4) runs on it too. One object, two changes: 3 + 4.

🤔 Think first

What can this do — and not do?

Can you use this in a static method? And is this.super.toString() valid?

Think about it, then reveal the answer

No to both. A static method isn't called on any object, so there **is no this** — using it doesn't compile. Valid uses: this.name = name, return this, passing this as an argument, and this(...) to call another constructor. this.super isn't legal syntax; write super.toString().

💼 In the real world

In real projects

return this powers the builder style you'll see everywhere: StringBuilder.append, HttpRequest.newBuilder().uri(...).GET().build(), and Lombok's @Builder. And this.x = x appears in nearly every constructor you'll ever read.

Key takeaways

  1. this = the object the code is running on
  2. this.x means the field; plain x may be a parameter
  3. return this; enables method chaining
  4. There is no this in a static method
🤯 Did you know?

Every instance method secretly receives this as a hidden first argument — in the bytecode it sits in local variable slot 0.

Practice questions

What does this print?

class Counter {
    int n;
    Counter add(int k) {
        n += k; return this;
    }
}
void main() {
    var c = new Counter();
    System.out.println(c.add(2).add(3).n);
}
  1. 3
  2. 5
  3. 2
  4. 0
Check your answer

5. add returns the same object it modified, so the second add runs on c again. n becomes 2 + 3 = 5.

What does this print?

class Util {
    int v = 3;
    static void show() {
        System.out.println(this.v);
    }
}
void main() {
    Util.show();
}
  1. 3
  2. 0
  3. Compile error
  4. Throws NullPointerException
Check your answer

Compile error. A static method is not called on any object, so there is no this. Using this in a static context does not compile.

Next: three constructors, one setup — chaining them together with this(...).