Your setter has void setName(String name). Inside, which name is which? The this keyword refers to the current object, letting you write this.name = name to distinguish the field from the parameter.

Disambiguate fields from parameters

Use this.field when names conflict.

Disambiguate.java
public class Disambiguate {
    public static void main(String[] args) {
        System.out.println("=== Disambiguating with 'this' ===\n");

        // Without 'this', names would shadow fields
        Person person = new Person("Alice", 30);
        System.out.println("Name: " + person.getName());
        System.out.println("Age: " + person.getAge());

        // Update using setters
        person.setName("Bob");
        person.setAge(25);
        System.out.println("\nAfter update:");
        System.out.println("Name: " + person.getName());
        System.out.println("Age: " + person.getAge());

        System.out.println("\n=== Why Same Names? ===");
        System.out.println("✓ Clear what the parameter represents");
        System.out.println("✓ No need to invent different names");
        System.out.println("✓ Common convention in Java");
    }
}

class Person {
    private String name;
    private int age;

    // Parameters have same name as fields
    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Getter - no disambiguation needed
    public String getName() {
        return name;  // Just 'name' is fine here
    }

    public int getAge() {
        return age;
    }

    // Setter - needs 'this' to disambiguate
    public void setName(String name) {
        this.name = name;  // this.name = field, name = parameter
    }

    public void setAge(int age) {
        this.age = age;
    }
}

this.name is the field. name alone is the parameter.

this Reference to the current object. Used to access fields and methods.

Method chaining

Return this to enable fluent interfaces.

MethodChaining.java
public class MethodChaining {
    public static void main(String[] args) {
        System.out.println("=== Method Chaining ===\n");
        int addAmount = ;

        // Traditional way: separate statements
        Counter counter1 = new Counter();
        counter1.increment();
        counter1.increment();
        counter1.add(addAmount);
        System.out.println("Traditional: " + counter1.getValue());

        // Chained way: single statement
        Counter counter2 = new Counter();
        counter2.increment().increment().add(addAmount);
        System.out.println("Chained: " + counter2.getValue());

        System.out.println("\n=== String Builder Pattern ===");

        // Build message fluently
        MessageBuilder builder = new MessageBuilder();
        String message = builder
            .append("Hello")
            .append(", ")
            .append("World")
            .append("!")
            .build();
        System.out.println("Message: " + message);

        System.out.println("\n=== Benefits ===");
        System.out.println("✓ More concise code");
        System.out.println("✓ Reads like natural language");
        System.out.println("✓ No need for temporary variables");
    }
}

class Counter {
    private int value = 0;

    // Returns 'this' to enable chaining
    public Counter increment() {
        value++;
        return this;  // Return the same object!
    }

    public Counter add(int amount) {
        value += amount;
        return this;  // Return the same object!
    }

    public Counter reset() {
        value = 0;
        return this;
    }

    public int getValue() {
        return value;
    }
}

class MessageBuilder {
    private StringBuilder sb = new StringBuilder();

    public MessageBuilder append(String text) {
        sb.append(text);
        return this;  // Enables: append("a").append("b")
    }

    public MessageBuilder appendLine(String text) {
        sb.append(text).append("\n");
        return this;
    }

    public String build() {
        return sb.toString();
    }
}
public class MethodChaining {
    public static void main(String[] args) {
        System.out.println("=== Method Chaining ===\n");
        int addAmount = ;

        // Traditional way: separate statements
        Counter counter1 = new Counter();
        counter1.increment();
        counter1.increment();
        counter1.add(addAmount);
        System.out.println("Traditional: " + counter1.getValue());

        // Chained way: single statement
        Counter counter2 = new Counter();
        counter2.increment().increment().add(addAmount);
        System.out.println("Chained: " + counter2.getValue());

        System.out.println("\n=== String Builder Pattern ===");

        // Build message fluently
        MessageBuilder builder = new MessageBuilder();
        String message = builder
            .append("Hello")
            .append(", ")
            .append("World")
            .append("!")
            .build();
        System.out.println("Message: " + message);

        System.out.println("\n=== Benefits ===");
        System.out.println("✓ More concise code");
        System.out.println("✓ Reads like natural language");
        System.out.println("✓ No need for temporary variables");
    }
}

class Counter {
    private int value = 0;

    // Returns 'this' to enable chaining
    public Counter increment() {
        value++;
        return this;  // Return the same object!
    }

    public Counter add(int amount) {
        value += amount;
        return this;  // Return the same object!
    }

    public Counter reset() {
        value = 0;
        return this;
    }

    public int getValue() {
        return value;
    }
}

class MessageBuilder {
    private StringBuilder sb = new StringBuilder();

    public MessageBuilder append(String text) {
        sb.append(text);
        return this;  // Enables: append("a").append("b")
    }

    public MessageBuilder appendLine(String text) {
        sb.append(text).append("\n");
        return this;
    }

    public String build() {
        return sb.toString();
    }
}
public class MethodChaining {
    public static void main(String[] args) {
        System.out.println("=== Method Chaining ===\n");
        int addAmount = ;

        // Traditional way: separate statements
        Counter counter1 = new Counter();
        counter1.increment();
        counter1.increment();
        counter1.add(addAmount);
        System.out.println("Traditional: " + counter1.getValue());

        // Chained way: single statement
        Counter counter2 = new Counter();
        counter2.increment().increment().add(addAmount);
        System.out.println("Chained: " + counter2.getValue());

        System.out.println("\n=== String Builder Pattern ===");

        // Build message fluently
        MessageBuilder builder = new MessageBuilder();
        String message = builder
            .append("Hello")
            .append(", ")
            .append("World")
            .append("!")
            .build();
        System.out.println("Message: " + message);

        System.out.println("\n=== Benefits ===");
        System.out.println("✓ More concise code");
        System.out.println("✓ Reads like natural language");
        System.out.println("✓ No need for temporary variables");
    }
}

class Counter {
    private int value = 0;

    // Returns 'this' to enable chaining
    public Counter increment() {
        value++;
        return this;  // Return the same object!
    }

    public Counter add(int amount) {
        value += amount;
        return this;  // Return the same object!
    }

    public Counter reset() {
        value = 0;
        return this;
    }

    public int getValue() {
        return value;
    }
}

class MessageBuilder {
    private StringBuilder sb = new StringBuilder();

    public MessageBuilder append(String text) {
        sb.append(text);
        return this;  // Enables: append("a").append("b")
    }

    public MessageBuilder appendLine(String text) {
        sb.append(text).append("\n");
        return this;
    }

    public String build() {
        return sb.toString();
    }
}

return this allows obj.setX(1).setY(2).setZ(3).

fluent interface Methods return `this` for chaining: `builder.setA(1).setB(2).build()`.

Pass this to other methods

Give the current object to another method or class.

PassThis.java
public class PassThis {
    public static void main(String[] args) {
        System.out.println("=== Passing 'this' to Methods ===\n");

        // Create registrar and tasks
        TaskRegistry registry = new TaskRegistry();

        Task task1 = new Task("Learn Java", registry);
        Task task2 = new Task("Practice coding", registry);
        Task task3 = new Task("Build projects", registry);

        System.out.println("=== Registry Status ===");
        registry.showAll();

        System.out.println("\n=== Completing a Task ===");
        task2.complete();

        System.out.println("\n=== Registry After Completion ===");
        registry.showAll();
    }
}

class Task {
    private String name;
    private boolean completed = false;

    Task(String name, TaskRegistry registry) {
        this.name = name;
        registry.register(this);
    }

    void complete() {
        completed = true;
        System.out.println("Completed: " + name);
    }

    String getStatus() {
        return name + (completed ? " [DONE]" : " [pending]");
    }
}

class TaskRegistry {
    private Task[] tasks = new Task[10];
    private int count = 0;

    void register(Task task) {
        if (count < tasks.length) {
            tasks[count++] = task;
            System.out.println("Registered: " + task.getStatus());
        }
    }

    void showAll() {
        System.out.println("All tasks (" + count + "):");
        for (int i = 0; i < count; i++) {
            System.out.println("  " + (i + 1) + ". " + tasks[i].getStatus());
        }
    }
}

someMethod(this) passes the current object as an argument.

Call another constructor

Use this() to invoke a different constructor.

ThisConstructor.java
public class ThisConstructor {
    public static void main(String[] args) {
        System.out.println("=== this() Constructor Calls ===\n");

        // Different ways to create Rectangle
        Rectangle r1 = new Rectangle();
        System.out.println("1. " + r1);

        Rectangle r2 = new Rectangle(5);  // Square
        System.out.println("2. " + r2);

        Rectangle r3 = new Rectangle(4, 6);
        System.out.println("3. " + r3);

        System.out.println("\n=== Notice Constructor Chain ===");
        System.out.println("Each simpler constructor calls a more complete one.");
        System.out.println("All eventually reach the main constructor.");
    }
}

class Rectangle {
    private double width;
    private double height;

    // Main constructor - all logic here
    Rectangle(double width, double height) {
        System.out.println("  [Main constructor: " + width + "x" + height + "]");
        this.width = Math.max(0, width);   // Validation
        this.height = Math.max(0, height);
    }

    // Square constructor - delegates to main
    Rectangle(double side) {
        this(side, side);  // Must be FIRST statement!
        System.out.println("  [Square constructor]");
    }

    // Default constructor - delegates to square
    Rectangle() {
        this(1);  // Unit square
        System.out.println("  [Default constructor]");
    }

    @Override
    public String toString() {
        return "Rectangle " + width + "x" + height;
    }
}

this(args) calls another constructor. Must be first line.

Builder pattern

Combine method chaining with a separate builder class.

BuilderPattern.java
public class BuilderPattern {
    public static void main(String[] args) {
        System.out.println("=== Builder Pattern ===\n");

        // Build an email step by step
        Email email = new EmailBuilder()
            .from("alice@example.com")
            .to("bob@example.com")
            .subject("Meeting Tomorrow")
            .body("Hi Bob,\nLet's meet at 10am.\n- Alice")
            .priority(EmailBuilder.Priority.HIGH)
            .build();

        System.out.println(email);

        System.out.println("\n=== Another Email ===");

        // Simpler email with defaults
        Email simple = new EmailBuilder()
            .to("team@example.com")
            .subject("Quick update")
            .build();

        System.out.println(simple);

        System.out.println("\n=== Benefits ===");
        System.out.println("✓ Optional parameters made easy");
        System.out.println("✓ Readable, self-documenting");
        System.out.println("✓ Immutable result object");
    }
}

class EmailBuilder {
    // Builder fields with defaults
    private String from = "noreply@example.com";
    private String to = "";
    private String subject = "(no subject)";
    private String body = "";
    private Priority priority = Priority.NORMAL;

    enum Priority { LOW, NORMAL, HIGH, URGENT }

    // Each setter returns 'this'
    public EmailBuilder from(String from) {
        this.from = from;
        return this;  // Enable chaining
    }

    public EmailBuilder to(String to) {
        this.to = to;
        return this;
    }

    public EmailBuilder subject(String subject) {
        this.subject = subject;
        return this;
    }

    public EmailBuilder body(String body) {
        this.body = body;
        return this;
    }

    public EmailBuilder priority(Priority priority) {
        this.priority = priority;
        return this;
    }

    // Final build method creates the object
    public Email build() {
        if (to.isEmpty()) {
            throw new IllegalStateException("'to' is required");
        }
        return new Email(from, to, subject, body, priority.name());
    }
}

class Email {
    private final String from, to, subject, body, priority;

    Email(String from, String to, String subject, String body, String priority) {
        this.from = from;
        this.to = to;
        this.subject = subject;
        this.body = body;
        this.priority = priority;
    }

    @Override
    public String toString() {
        return String.format(
            "=== Email [%s] ===\nFrom: %s\nTo: %s\nSubject: %s\n---\n%s",
            priority, from, to, subject, body.isEmpty() ? "(no body)" : body
        );
    }
}

Builder accumulates settings, then creates the final object.

Exercise: CompleteExample.java

Comprehensive example combining all uses of this