1. Reference Guide

Key Topics

Term Definition Example
this A reference to the current object inside a constructor or instance method. this.failedAttempts
Instance variable A field whose value belongs to an individual object. private int failedAttempts;
Parameter A variable that receives an argument when a method or constructor is called. int failedAttempts in a constructor header
Shadowing A parameter or local variable hides a field with the same name. Use this.failedAttempts to reach the hidden field.
Self-assignment Assigning a variable to itself; it does not update the hidden field. failedAttempts = failedAttempts;
Instance method A method called on an object, which supplies the this reference. jade.printInfo();
Static method A method with no current-object reference. main must use an explicit object such as jade.

Choosing How to Refer to an Object

  • Use this.field = parameter; when the parameter and field have the same name.
  • Use this.method() to call an instance method on the current object; this. is optional when there is no ambiguity.
  • Use monitor.inspectAccount(this) to pass the current object to another method.
  • In a static method, use an explicit object reference instead of this.

2. LxD Cycle Process

Empathize: Students may read failedAttempts = failedAttempts; as an update to an object’s field, or assume that this always refers to the same object. Begin by asking students to predict what happens when two accounts call the same method.

Define:

  • POV: CSA students need to distinguish an object’s fields from local parameters because code can compile while updating the wrong variable.
  • Learning Goal: Students will identify the current object, fix shadowed-field assignments, pass this as an argument, and explain why static methods cannot use it.

Ideate:

  • HMW Question: How might we make the object receiving each method call visible while students trace code?
  • HMW Question: How might we help students explain why self-assignment compiles but leaves a field unchanged?
  • Activity: Trace Jade’s and Alex’s accounts, label both sides of a constructor assignment, and repair a setter with a partner.

Prototype:

  • Use the reference guide, the complete Account example, Popcorn Hacks, and the trace-and-debug practice below.
  • Have students predict output, run the example, and revise their explanation when the output differs.
  • Excellence means explaining which object changes and why, rather than only producing code that compiles.

Test:

  • Ask a peer to complete the account trace and setter repair without additional explanation.
  • Check whether the peer distinguishes a parameter from a field and identifies the receiving object correctly.
  • Collect predicted and actual output, the repaired setter, and an explanation of the static-method error.
  • Use the PasswordPolicy homework to check independent application with two objects.
  • After teaching and reviewing student work, revise examples or prompts that left misconceptions unresolved.

3. College Board Requirements

AP CSA Unit 3, Topic 3.9: this Keyword. The requirements below are paraphrased from the College Board AP Computer Science A Course and Exam Description, effective Fall 2025, printed page 90.

  • 3.9.A — Learning Objective: Write and trace expressions that refer to the current object.
  • 3.9.A.1 — Essential Knowledge: In constructors and instance methods, this refers to the object being initialized or receiving the call.
  • 3.9.A.2 — Essential Knowledge: A method call can receive the current object by using this as an argument.
  • 3.9.A.3 — Essential Knowledge: Static (class) methods have no this reference.

Lesson alignment: The Account trace and shadowing repair practice 3.9.A.1; requestReview practices 3.9.A.2; the static-method debugging example practices 3.9.A.3. Constructor chaining and return this remain optional enrichment beyond these listed requirements.


4. Lesson Plan

Learning Objective: Use this to access the current object’s fields and methods, resolve parameter shadowing, and pass the current object as an argument.

Success Criteria: You can identify the receiving object in a trace, repair a shadowed assignment, explain why passing this does not create a copy, and explain why this is unavailable in a static method.

Tech Talk (5 minutes)

this means “the object whose constructor or instance method is running.” In the Account constructor, label each side of this assignment:

this.failedAttempts = failedAttempts;
// object's field     constructor parameter

Compare jade.printInfo() and alex.printInfo(): the same method runs with a different current object each time. A static method such as main has no current object.

Guided Code Examples (10 minutes)

Run the complete Account example in Section 5. Predict Jade’s and Alex’s counts first, then compare them with the output. Walk through parameter shadowing, the self-assignment bug, passing this to SecurityMonitor, and the static-method error.

Popcorn Hacks (8 minutes)

Complete the short challenges beside the examples: add a third account, repair setFailedAttempts, and change the monitor to update the incoming account. Explain which object each change affects.

Knowledge Check and Peer Review (5 minutes)

Answer the trace and debugging questions in Section 6 before reading the answer check. Compare reasoning with a partner and revise any incorrect prediction.

Exit Ticket (2 minutes)

Explain what each side of this.failedAttempts = failedAttempts; refers to, then explain why the same expression cannot appear in a static method without an object reference replacing this.

Homework Hack

Complete the PasswordPolicy task in Section 6. Include your code, output from two objects, and a short explanation of why updating one object’s minimum length leaves the other unchanged.


5. Code Examples

What Does this Mean?

this is a reference to the current object. In a constructor, it refers to the object being initialized. In an instance method, it refers to the object receiving the call.

Each example below is a complete, independent Java code runner, just like lesson 1.2. Predict the output, click Run, then edit and rerun it.

A. Tracking Failed Password Logins

Each account has its own fields. For jade.recordFailures(5), this refers to Jade’s account; for alex.printInfo(), it refers to Alex’s account.

Code Runner Challenge

Predict both account counts, then run and add a third account.

View IPYNB Source
// CODE_RUNNER: Predict both account counts, then run and add a third account.
public class Account {
    private String username;
    private int failedAttempts;

    public Account(String username, int failedAttempts) {
        this.username = username;
        this.failedAttempts = failedAttempts;
    }

    public void recordFailures(int attempts) {
        this.failedAttempts += attempts;
    }

    public void printInfo() {
        System.out.println(this.username + ": " + this.failedAttempts);
    }

    public static void main(String[] args) {
        Account jade = new Account("Jade", 10);
        Account alex = new Account("Alex", 20);

        jade.recordFailures(5);
        jade.printInfo();
        alex.printInfo();
    }
}

Account.main(null);

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Expected output: Jade: 15 and Alex: 20.

Popcorn Hack: Add a third account, record failures for it, and explain why the other accounts do not change.

B. Parameter Shadowing and Self-Assignment

A parameter with the same name as a field hides that field. In this.failedAttempts = failedAttempts;, the left side is the object’s field and the right side is the parameter.

The next constructor intentionally assigns each parameter to itself. It compiles, but leaves the fields at their default values, so it prints null: 0. Local variables do not automatically receive field defaults.

Code Runner Challenge

Run the buggy constructor, then fix both assignments with this.

View IPYNB Source
// CODE_RUNNER: Run the buggy constructor, then fix both assignments with this.
public class Account {
    private String username;
    private int failedAttempts;

    public Account(String username, int failedAttempts) {
        username = username;
        failedAttempts = failedAttempts;
    }

    public void recordFailures(int attempts) {
        this.failedAttempts += attempts;
    }

    public void printInfo() {
        System.out.println(this.username + ": " + this.failedAttempts);
    }


    public static void main(String[] args) {
        Account jade = new Account("Jade", 10);
        jade.printInfo();
    }
}

Account.main(null);

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

C. When Is this Optional?

When parameter names differ from field names, there is no shadowing and the constructor can use plain field names. A getter without shadowing can likewise use either failedAttempts or this.failedAttempts.

Popcorn Hack: The constructor below works, but the setter contains a self-assignment bug. Fix it so the output changes from Jade: 10 to Jade: 2. Explain both sides of the corrected assignment.

Code Runner Challenge

Repair the setter, then verify that it prints Jade: 2.

View IPYNB Source
// CODE_RUNNER: Repair the setter, then verify that it prints Jade: 2.
public class Account {
    private String username;
    private int failedAttempts;

    public Account(String accountUsername, int initialAttempts) {
        username = accountUsername;
        failedAttempts = initialAttempts;
    }

    public void recordFailures(int attempts) {
        this.failedAttempts += attempts;
    }

    public void printInfo() {
        System.out.println(this.username + ": " + this.failedAttempts);
    }

    public void setFailedAttempts(int failedAttempts) {
        failedAttempts = failedAttempts; // TODO: update the field instead.
    }

    public static void main(String[] args) {
        Account jade = new Account("Jade", 10);
        jade.setFailedAttempts(2);
        jade.printInfo();
    }
}

Account.main(null);

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

D. Calling an Instance Method with this

this.recordFailures(1) and this.printInfo() call methods on the same current object. Here, omitting this. has the same effect.

Code Runner Challenge

Run it, then remove this. from the two method calls and compare.

View IPYNB Source
// CODE_RUNNER: Run it, then remove this. from the two method calls and compare.
public class Account {
    private String username;
    private int failedAttempts;

    public Account(String username, int failedAttempts) {
        this.username = username;
        this.failedAttempts = failedAttempts;
    }

    public void recordFailures(int attempts) {
        this.failedAttempts += attempts;
    }

    public void printInfo() {
        System.out.println(this.username + ": " + this.failedAttempts);
    }

    public void recordFailedLogin() {
        this.recordFailures(1);
        this.printInfo();
    }

    public static void main(String[] args) {
        Account jade = new Account("Jade", 10);
        jade.recordFailedLogin();
    }
}

Account.main(null);

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

E. Passing this as an Argument

monitor.inspectAccount(this) passes the current account to another method. The monitor’s account parameter refers to the same object as jade; no account is copied.

The helper class is nested here so the complete example fits in one runnable class.

Code Runner Challenge

Have the monitor record three failures; predict both printed counts.

View IPYNB Source
// CODE_RUNNER: Have the monitor record three failures; predict both printed counts.
public class Account {
    private String username;
    private int failedAttempts;

    public Account(String username, int failedAttempts) {
        this.username = username;
        this.failedAttempts = failedAttempts;
    }

    public void recordFailures(int attempts) {
        this.failedAttempts += attempts;
    }

    public void printInfo() {
        System.out.println(this.username + ": " + this.failedAttempts);
    }

    public void requestReview(SecurityMonitor monitor) {
        monitor.inspectAccount(this);
    }

    static class SecurityMonitor {
        public void inspectAccount(Account account) {
            // Popcorn Hack: record three failures for account here.
            System.out.print("Security review: ");
            account.printInfo();
        }
    }

    public static void main(String[] args) {
        Account jade = new Account("Jade", 10);
        SecurityMonitor monitor = new SecurityMonitor();
        jade.requestReview(monitor);
        jade.printInfo();
    }
}

Account.main(null);

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Popcorn Hack: Add account.recordFailures(3); in inspectAccount. Both prints should show 13 because both references reach the same account.

F. Why Static Methods Cannot Use this

Static methods have no current object. Run both valid alternatives below: an instance method using this and a static method using an explicit account reference.

Then uncomment the marked line to observe the compile-time error. Comment it again to restore the working example. The static method can access the private field because it is declared inside Account.

Code Runner Challenge

Run both alternatives, then uncomment the invalid line to see the error.

View IPYNB Source
// CODE_RUNNER: Run both alternatives, then uncomment the invalid line to see the error.
public class Account {
    private String username;
    private int failedAttempts;

    public Account(String username, int failedAttempts) {
        this.username = username;
        this.failedAttempts = failedAttempts;
    }

    public void recordFailures(int attempts) {
        this.failedAttempts += attempts;
    }

    public void printInfo() {
        System.out.println(this.username + ": " + this.failedAttempts);
    }

    public void showFailedAttempts() {
        System.out.println(this.failedAttempts);
    }

    public static void showFailedAttempts(Account account) {
        System.out.println(account.failedAttempts);
        // System.out.println(this.failedAttempts); // Invalid in a static method.
    }

    public static void main(String[] args) {
        Account jade = new Account("Jade", 10);
        jade.showFailedAttempts();
        Account.showFailedAttempts(jade);
    }
}

Account.main(null);

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

G. Optional Extension: this(...) and return this

this(username, 0) delegates initialization to another constructor in the same class. It still initializes just one object. Keep this constructor call first, and never create a cycle of constructor calls.

return this returns that same object, allowing method calls to be chained. These are enrichment topics beyond the listed Topic 3.9 requirements.

Code Runner Challenge

Predict the result of the chained calls, then run it.

View IPYNB Source
// CODE_RUNNER: Predict the result of the chained calls, then run it.
public class Account {
    private String username;
    private int failedAttempts;

    public Account(String username, int failedAttempts) {
        this.username = username;
        this.failedAttempts = failedAttempts;
    }

    public void recordFailures(int attempts) {
        this.failedAttempts += attempts;
    }

    public void printInfo() {
        System.out.println(this.username + ": " + this.failedAttempts);
    }

    public Account(String username) {
        this(username, 0);
    }

    public Account recordAttempts(int attempts) {
        this.failedAttempts += attempts;
        return this;
    }

    public static void main(String[] args) {
        Account sam = new Account("Sam");
        sam.recordAttempts(5).recordAttempts(2);
        sam.printInfo();
    }
}

Account.main(null);

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

6. Hacks & Practice Tasks

Practice: Trace and Debug

1. Predict the Output

Code Runner Challenge

Choose your answer before running, then explain why attempts++ does not change the field.

View IPYNB Source
// CODE_RUNNER: Choose your answer before running, then explain why attempts++ does not change the field.
public class LoginTracker {
    private int attempts;

    public LoginTracker(int attempts) {
        this.attempts = attempts;
    }

    public void recordFailures(int attempts) {
        this.attempts += attempts;
        attempts++;
    }

    public int getAttempts() {
        return attempts;
    }
    public static void main(String[] args) {
        LoginTracker tracker = new LoginTracker(4);
        tracker.recordFailures(3);
        System.out.println(tracker.getAttempts());
    }
}

LoginTracker.main(null);

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Which value is printed?

  • A. 3
  • B. 4
  • C. 7
  • D. 8

2. Identify the Error

Why does failedAttempts = failedAttempts; compile in the buggy constructor, while this.failedAttempts inside a static method fails to compile?

3. Homework Hack: Apply the Idea

Create a PasswordPolicy class with a String label field (such as "Training Portal") and an int minimumLength field. Include:

  1. A constructor whose parameter names match the fields.
  2. A setMinimumLength(int minimumLength) method.
  3. A method that prints the password policy’s information.
  4. Two objects demonstrating that changing one does not affect the other.

Complete the TODOs in this runnable homework starter.

Code Runner Challenge

Complete the constructor and setter; expect School: 12 and Club: 10.

View IPYNB Source
// CODE_RUNNER: Complete the constructor and setter; expect School: 12 and Club: 10.
public class PasswordPolicy {
    private String label;
    private int minimumLength;

    public PasswordPolicy(String label, int minimumLength) {
        // TODO: initialize both fields from the matching parameters.
    }

    public void setMinimumLength(int minimumLength) {
        // TODO: update this object's field.
    }

    public void printInfo() {
        System.out.println(this.label + ": " + this.minimumLength);
    }

    public static void main(String[] args) {
        PasswordPolicy school = new PasswordPolicy("School", 8);
        PasswordPolicy club = new PasswordPolicy("Club", 10);
        school.setMinimumLength(12);
        school.printInfo();
        club.printInfo();
    }
}

PasswordPolicy.main(null);

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Answer Check

  1. C: 7. this.attempts += attempts adds three to the field. attempts++ changes only the local parameter, so the field stays seven.
  2. Self-assignment is legal Java even though it fails to update the intended field. A static method has no current object, so this is unavailable.
  3. The constructor should use this.label = label; and this.minimumLength = minimumLength;. The setter should use this.minimumLength = minimumLength;.

Quick Review

  • Identify the object receiving the call to determine what this means.
  • Check parameter and local-variable names before tracing a field update.
  • Use this.field to access a field hidden by a parameter.
  • Passing or returning this does not copy the object.
  • Static methods need an explicit object reference to access instance data.

7. Sources


8. Submit Your Work

  1. Create your homework notebook in _notebooks/homework with Java code cells. Use one runnable class per cell, ending with ClassName.main(null);.
  2. Include your completed Popcorn Hacks, trace answer and reasoning, static-method error explanation, and PasswordPolicy homework. Run each cell and keep its output visible.
  3. Use Submit Assignment below: choose Link Submission for your published homework URL, or File Upload to upload your work.
  4. In the description or notes, include:
Lesson: CSA 3.9 this Keyword
Popcorn: third account, fixed setter, and monitor update completed
Trace answer and explanation: <your answer>
Why static methods cannot use this: <your explanation>
Homework output: <both policy values>
Why changing one policy leaves the other unchanged: <your explanation>

Submit Assignment

Your code will be saved as a Gist and reviewed automatically. You must be logged in to submit.

Need to update a submission later? Open the submissions dashboard.