When to Use the Java "this" Keyword

A definitive guide, with examples, on one of the most omnipresent Java keywords.

Last Updated on May 23, 2020 · 4 min read
Post cover image
Photo by Nick van den Berg on Unsplash

Code reviews are the gift that keeps on giving. Even after you go through them with your colleagues, the potential for further discoveries is undervalued.

The other day I was checking some comments on a pull request and I found something along the lines of:

"this" is not needed here.

and this was the Java keyword. In that part of the code it was being used to assign a mock to a test class variable. Something like:

public class FooTest {
    
    private Foo foo;
    
    @Before
    private setup() {
        this.foo = mockFoo();
    }
}

And you know what, he's 100% right. The test runs as expected, but we don't need this in this case.

An atomic explanation of what's the Java this keyword

With this you get a direct reference to the current object from inside one of its methods1.

That's it.

I bet you also imagine the potential for confusion and redundancy in its use. If you can also access the current object's methods and variables without employing the this keyword, why would you need a special keyword for that?

Because you might be facing one of these five scenarios:

When there's ambiguity between instance variables and method parameters

Java best practices promote a specific way of writing setter methods.

public class Car {
    private String color;
    
    public void setColor(String color) {
    	this.color = color;
	}
}

I'll go ahead and risk saying that this is the most common use for this. When a method accepts a parameter with the same name as one of its object's variables you need a way to identify which is which.

When you want to call a constructor from another in the same class

If you accept different sets of parameters to create the same type of object, chances are you are either using a builder or overloaded constructors. When it's the latter, and independently of what constructor is called, you might need to call another to take care of default properties that should always be part of the initial object definition.

public class Car {
    private String color;
    private String model;
    private boolean looksGood; 
    
    public Car(String color) {
        this(color, "100A");
    }
    
    public Car(String color, String model) {
        this.color = color;
        this.model = model;
        this.looksGood = true;
    }
}

Once again this to the rescue. This time we use it to reference a method (a constructor more specifically) from inside of another. Important Java rule to remember: this() needs to be the first statement in each constructor calling another one.

When you need to return the current class instance from a method

This is the rule that gives power to the builder design pattern. You can chain consecutive properties to an object definition because with each addition you get in return the updated object. That updated object is returned by this.

public class Car {
    private String color;
    private String model;
    private boolean looksGood; 
    
    public static final class CarBuilder {
        private String color;
        private String model;
        private boolean looksGood;

        private CarBuilder() {
        }

        public static CarBuilder aCar() {
            return new CarBuilder();
        }

        public CarBuilder withColor(String color) {
            this.color = color;
            return this;
        }

        public CarBuilder withModel(String model) {
            this.model = model;
            return this;
        }

        public Car build() {
            Car car = new Car();
            car.color = this.color;
            car.model = this.model;
            car.looksGood = true;
            return car;
        }
    }
}

And once you see it in action is more impressive:

Car fineCar = aCar()
    .withColor("blue")
    .withModel("100A")
    .build();

Like an assembly line, here a Car is also built step by step, with each station getting all the work done before, and adding a little bit to it.

When you need to pass the current class instance to a method

Just as easy as you return this from a method you can pass it as a parameter in another. With them they take their instance variables and methods, allowing their access in other classes. With great power comes great responsibility!

public class Car {
    private String color;
    
    public void setColor(String color) {
    	this.color = color;
	}
    
    public void paint(String newColor) {
        PaintShop shop = new PaintShop();
        return shop.paint(this, newColor);
    }
}

public class PaintShop {
    
    private boolean willItMakeMyCarLookGood(String color) {
        return true;
    }
    
    public void paint(Car car, String color) {
        if (willItMakeMyCarLookGood(color)) {
        	car.setColor(color);
        }
    }
}

When a nested, non-static, class needs to access the instance of the outer class

We have to look at a nested class as any other member of the outer class.

Something cool that I only learned when writing this article. Non-static nested classes are called inner classes, while static ones are called static nested classes2.

Like a method in the examples above, it is only expectable that Java allows you to get a reference that parent class instance through this keyword.

public class Car {
    private String model;
    
    public class Engine {
        protected String maxPower;
        
        public void setMaxPower() {
            if ("100A".equals(Car.this.model)) {
                this.maxPower = "100 bhp";
            } else if ("120A".equals(Car.this.model)) {
                this.maxPower = "120 bhp";
            } else {
                this.maxPower = "90 bhp";
            }
        }     
    }
}

This feature of the this keyword, allows you to not just access the Car instance variables, like in the example, but if needed, the Car instance itself.


  1. You also get one of the most used English words, making writing this article an excellent exercise in creativity and self-control.

    ↩
  2.  Nested Classes documentation

    ↩


If you enjoyed this, there are many others to come.

This Week's Worth preamble

This is my (almost) weekly newsletter.

You should consider be part of it to stay on top of new articles and other stuff I have yet to figure out. Yup, I'm improvising here.