The this Keyword in Java

Inside an instance method, this is a reference to the object the method was called on, which resolves shadowing and enables chaining.

Definition

this is a reference to the current object. It is available in every instance method, constructor and instance initialiser block, and it is not available in a static context because there is no current object there.

Its four uses

1. Distinguishing a field from a parameter

public class Product {

    private String name;
    private double price;

    public Product(String name, double price) {
        this.name = name;      // field = parameter
        this.price = price;
    }
}

The parameter shadows the field, so a plain name refers to the parameter. Without this, name = name; assigns the parameter to itself and the field stays null, which compiles cleanly and fails silently.

2. Calling another constructor

public class Order {

    private final String reference;
    private final int quantity;

    public Order(String reference) {
        this(reference, 1);        // must be the first statement
    }

    public Order(String reference, int quantity) {
        this.reference = reference;
        this.quantity = quantity;
    }
}

3. Returning the current object for chaining

public class QueryBuilder {

    private final StringBuilder sql = new StringBuilder("SELECT * FROM notes");

    public QueryBuilder where(String condition) {
        sql.append(" WHERE ").append(condition);
        return this;
    }

    public QueryBuilder orderBy(String column) {
        sql.append(" ORDER BY ").append(column);
        return this;
    }

    public String build() {
        return sql.toString();
    }
}
String query = new QueryBuilder()
        .where("status = 1")
        .orderBy("created_at")
        .build();

4. Passing the current object to something else

public class Order {

    public void submit(OrderValidator validator) {
        validator.check(this);     // hand the whole object over
    }
}

Explicit method calls

public class Report {

    public void print() {
        this.render();     // identical to render()
        render();
    }

    private void render() { }
}

this before a method call is optional and adds nothing. Some teams use it for emphasis; most omit it.

Rules

  • this cannot be used inside a static method or a static initialiser.
  • this(...) and super(...) cannot both appear in one constructor, and either must be the first statement.
  • this cannot be reassigned; it is effectively final.
  • In an inner class, this means the inner instance. Use Outer.this to reach the enclosing one.
public class Outer {

    private String label = "outer";

    class Inner {
        private String label = "inner";

        void show() {
            System.out.println(this.label);        // inner
            System.out.println(Outer.this.label);  // outer
        }
    }
}

this in lambdas

public class Service {

    private final String name = "service";

    public Runnable asLambda() {
        return () -> System.out.println(this.name);   // the Service instance
    }

    public Runnable asAnonymousClass() {
        return new Runnable() {
            @Override
            public void run() {
                // this here would be the Runnable, not the Service
                System.out.println(Service.this.name);
            }
        };
    }
}
A lambda does not introduce a new this. It sees the enclosing instance directly, which is one of the practical differences between a lambda and an anonymous class.

Common mistakes

  • Writing name = name; in a constructor and leaving the field null.
  • Trying to use this in main or any other static method.
  • Placing this(...) anywhere but the first line of a constructor.
  • Leaking this from a constructor by registering the half built object with a listener or a collection.

Best practices

  • Use this.field = parameter in constructors and setters, and give the parameter the same name as the field.
  • Return this from mutating methods only when a fluent API is genuinely intended.
  • Do not publish this before the constructor finishes.
  • Skip this before ordinary method calls unless the codebase has a standing convention.

Practice

  1. Remove this from a constructor that assigns same named parameters and explain what the object looks like afterwards.
  2. Write a small fluent builder with three chained methods.
  3. Why is this unavailable in public static void main?
  4. In a nested class, print both the inner and the outer field of the same name.
  5. Explain what a lambda sees when it refers to this, and how that differs from an anonymous class.

Conclusion

Reach for this when a name is shadowed, when one constructor should delegate to another, when a method should return the object for chaining, or when the object itself has to be handed to someone else.

Written by Lorens Mishra

Default administrator account created by the installer.

Continue reading

All Java notes →

Discussion

0 comments
Sign in to join the discussion.

No comments yet. Be the first to say something.