Skip to content

Java this Keyword

Updated 8 min read Aimerscrew

Inside a method, how does an object talk about itself? With the Java this keyword. this is a reference to the current object: the one whose method or constructor is running right now. In this lesson, you'll use this to fix a classic constructor bug, chain constructors, hand the current object to another object, and write methods you can chain together like order.size("large").milk("oat").

🌍 Real-life example

When you fill in a hotel check-in form, the line "My name is ___" doesn't need to say which guest it means. Whoever is filling in the form, "my" means that person. In Java, this works like "my": inside a method, it always means the object the method was called on.

What is the this keyword in Java?

this is a built-in reference that every non-static method and constructor gets for free. It points to the object the code is currently working on. When you call morning.addSteps(3200), this inside addSteps refers to morning. Call evening.addSteps(5100), and the very same code now has this referring to evening.

public class TwoCounters {
    public static void main(String[] args) {
        StepCounter morning = new StepCounter("Morning walk");
        StepCounter evening = new StepCounter("Evening run");

        morning.addSteps(3200);
        evening.addSteps(5100);
        morning.addSteps(800);
    }
}

class StepCounter {
    String label;
    int steps;

    StepCounter(String label) {
        this.label = label;
    }

    void addSteps(int steps) {
        this.steps += steps;
        System.out.println(this.label + ": " + this.steps + " steps");
    }
}
Morning walk: 3200 steps
Evening run: 5100 steps
Morning walk: 4000 steps
Animation: the method addSteps contains this.steps += steps; when morning.addSteps(3200) is called, this points to the morning object; when evening.addSteps(5100) is called, this points to the evening object
One method, many objects. this is whichever object came before the dot.

Using this to refer to fields (fixing shadowing)

In the Java constructors lesson, we gave parameters different names, like ownerName, to keep them apart from the fields. Most Java code uses the same name for both, because it's clearer. But that causes a problem. Can you spot the bug?

public class ShadowBug {
    public static void main(String[] args) {
        Student s = new Student("Aiko", 21);
        System.out.println(s.name + " is " + s.age);
    }
}

class Student {
    String name;
    int age;

    Student(String name, int age) {
        name = name;   // oops: assigns the parameter to itself
        age = age;
    }
}
null is 0

Inside the constructor, the parameter name shadows (hides) the field name. When two variables have the same name, Java uses the closest one, the parameter, as you saw in Java variable scope. So name = name; copies the parameter into itself, and the field stays null.

The fix is this.name, which means "the name field of this object":

public class ShadowFixed {
    public static void main(String[] args) {
        Student s = new Student("Aiko", 21);
        System.out.println(s.name + " is " + s.age);
    }
}

class Student {
    String name;
    int age;

    Student(String name, int age) {
        this.name = name;   // field = parameter
        this.age = age;
    }
}
Aiko is 21

Read this.name = name; as "my name field gets the name I was given". This pattern appears in almost every Java class you'll ever read.

📝 Note

When there's no name clash, this. is optional. In addSteps above, this.label and plain label mean the same thing. Many developers only write this. when they need it.

Calling another constructor with this(...)

this followed by parentheses is different: this(...) calls another constructor of the same class. You met it in the last lesson. Combined with this.field = field, it gives you short, readable constructors:

public class AlarmClock {
    public static void main(String[] args) {
        Alarm weekday = new Alarm(6, 45, "Work");
        Alarm quick = new Alarm(7, 30);
        Alarm nap = new Alarm();

        weekday.show();
        quick.show();
        nap.show();
    }
}

class Alarm {
    int hour;
    int minute;
    String label;

    Alarm() {
        this(14, 0);                    // a 2 PM nap alarm
    }

    Alarm(int hour, int minute) {
        this(hour, minute, "Alarm");
    }

    Alarm(int hour, int minute, String label) {
        this.hour = hour;
        this.minute = minute;
        this.label = label;
    }

    void show() {
        System.out.printf("%s at %02d:%02d%n", label, hour, minute);
    }
}
Work at 06:45
Alarm at 07:30
Alarm at 14:00
FormMeaningWhere you can use it
this.fieldA field of the current objectAny constructor or non-static method
this.method()Call a method on the current objectAny constructor or non-static method
this(...)Call another constructor of this classOnly as the first line of a constructor
this on its ownThe current object as a valuePass it or return it

Passing this to another object

Because this is a reference, you can pass it to a method like any other value. That's how an object introduces itself to another object. Here, an order assigns itself to a delivery driver:

public class DeliveryApp {
    public static void main(String[] args) {
        Driver driver = new Driver("Carlos");

        Order sushi = new Order("Sushi platter", "12 Baker Street");
        Order tacos = new Order("Taco box", "88 Pine Avenue");

        sushi.assignTo(driver);
        tacos.assignTo(driver);

        System.out.println(driver.name + " finished " + driver.deliveries + " deliveries.");
    }
}

class Order {
    String dish;
    String address;

    Order(String dish, String address) {
        this.dish = dish;
        this.address = address;
    }

    void assignTo(Driver driver) {
        driver.deliver(this);           // pass the current order to the driver
    }
}

class Driver {
    String name;
    int deliveries;

    Driver(String name) {
        this.name = name;
    }

    void deliver(Order order) {
        deliveries++;
        System.out.println(name + " is taking the " + order.dish + " to " + order.address);
    }
}
Carlos is taking the Sushi platter to 12 Baker Street
Carlos is taking the Taco box to 88 Pine Avenue
Carlos finished 2 deliveries.

When sushi.assignTo(driver) runs, this is the sushi order, so the driver receives a reference to it and can read its dish and address.

Returning this for method chaining

A method can also return this. The caller gets the same object back, so it can immediately call another method on it. Chaining calls like this is called a fluent style, and it reads almost like a sentence:

public class CoffeeApp {
    public static void main(String[] args) {
        CoffeeOrder order = new CoffeeOrder("Mia")
                .size("large")
                .milk("oat")
                .extraShot()
                .extraShot();

        order.print();
    }
}

class CoffeeOrder {
    String customer;
    String size = "medium";
    String milk = "whole";
    int shots = 1;

    CoffeeOrder(String customer) {
        this.customer = customer;
    }

    CoffeeOrder size(String size) {
        this.size = size;
        return this;                    // hand back the same object
    }

    CoffeeOrder milk(String milk) {
        this.milk = milk;
        return this;
    }

    CoffeeOrder extraShot() {
        shots++;
        return this;
    }

    void print() {
        System.out.println(customer + ": " + size + " latte, " + milk + " milk, " + shots + " shots");
    }
}
Mia: large latte, oat milk, 3 shots

Two new details here. First, fields can have starting values right where they're declared (String size = "medium";); they're set before the constructor body runs. Second, each method's return type is CoffeeOrder, because it returns the object itself. new CoffeeOrder("Mia") creates the object, .size("large") changes it and returns it, .milk("oat") works on that same object, and so on. Only one object is ever created.

💡 Tip

You've already used this style: StringBuilder methods such as append() return the builder itself, which is why sb.append("a").append("b") works.

Where can't you use this?

this only exists when there is a current object. A static method, such as main, belongs to the class rather than to any object, so writing this inside main is a compile error: "non-static variable this cannot be referenced from a static context". You'll learn exactly why in the Java static keyword.

You also can't assign to it: this = otherOrder; doesn't compile. this always points to the object that's running the code.

Common mistakes with this

1. Forgetting this when names clash

name = name; in a constructor silently does nothing useful. Your fields stay null or 0. Write this.name = name;.

2. Using this in a static method

main has no current object, so this isn't available there. Create an object and use its variable instead.

3. Putting this(...) anywhere but the first line

A constructor call must come first; any statement before it is a compile error.

4. Forgetting return this in a fluent method

If a method is declared void, you can't chain another call after it. Give it the class as its return type and end it with return this;.

Practice exercise

🏋️ Try it yourself

Create a Track class for a music app with fields title, artist (default "Unknown") and rating. The constructor takes the title and uses this. Add fluent methods artist(String artist) and rating(int rating) that return this, plus a show() method. Build "Midnight City" by M83 rated 5 in a single chained expression and print it.

Show solution
public class Playlist {
    public static void main(String[] args) {
        Track track = new Track("Midnight City")
                .artist("M83")
                .rating(5);

        track.show();
    }
}

class Track {
    String title;
    String artist = "Unknown";
    int rating;

    Track(String title) {
        this.title = title;
    }

    Track artist(String artist) {
        this.artist = artist;
        return this;
    }

    Track rating(int rating) {
        this.rating = rating;
        return this;
    }

    void show() {
        System.out.println(title + " by " + artist + ", rated " + rating + "/5");
    }
}
Midnight City by M83, rated 5/5

What's next?

So far, any code could reach into an object and change its fields directly. Next, learn Java access modifiers: public, private, protected and package-private, which control who is allowed to touch what.

Key takeaways

  • this is a reference to the current object, the one whose method or constructor is running.
  • Use this.field = field; when a parameter has the same name as a field.
  • Without this, a parameter shadows the field and the assignment does nothing useful.
  • this(...) calls another constructor of the same class and must be the first statement.
  • You can pass this to another object's method to hand over the current object.
  • Returning this from methods enables fluent method chaining.
  • this does not exist in static methods such as main.

Frequently asked questions

What does the this keyword mean in Java?

this is a reference to the current object. Inside a method or constructor, it points to the object the code was called on, so this.name means the name field of that object.

Why do we use this.name = name in a constructor?

When a parameter has the same name as a field, the parameter hides the field. this.name refers to the field, so this.name = name copies the parameter value into the field.

What is the difference between this and this() in Java?

this is a reference to the current object. this(...) is a call to another constructor in the same class, and it is only allowed as the first statement of a constructor.

Can you use this in a static method?

No. A static method belongs to the class, not to an object, so there is no current object for this to refer to. Using it causes a compile error.

What does return this do?

It returns the current object to the caller, so the caller can call another method on it straight away. This is how fluent method chaining like obj.a().b().c() works.