3.06 Methods Passing and Returning References of an Object


1. Reference Guide

Key Topics

Term Definition Example
Reference The address of an object. An object variable stores this, not the object itself. Shape s = new Shape("square", 4, 4);
Parameter copy Passing an object gives the method a copy of the reference, not a copy of the object. grow(rect);
Mutate Change a field on the object a reference points to. s.set_width(10);
Reassign Point a variable at a different object. s = new Shape("new", 1, 1);
Alias Two variables holding the same reference. Shape b = a;

Reference Anatomy

Line What it does
s.set_width(10) Mutate - changes a field on the object s points to
s = new Shape(...) Reassign - points s at a brand-new object
Shape b = a; Alias - b becomes a second reference to a’s object
return s; Returns the same reference, not a copy of the object
return new Shape(...); Returns a brand-new, independent object

Predicting the Result

Inside the method… Does the caller see it?
A . call or field change on the parameter Yes - same object
The parameter on the left of = No - only the local copy moved
return of a parameter The result is an alias
return new ... The result is independent

2. LxD Cycle Process

Empathize

Students treat “passing an object” and “passing a copy” as the same thing, so a demo’s output feels random. They expect every change inside a method to disappear, or every reassignment to reach back into the caller.

Define

  • POV: Students need a reliable way to predict whether a method call changes the caller’s object, because getting it wrong produces bugs that look random.
  • Learning Goal: Students will trace an object reference into and out of a method, and predict when the caller’s object is mutated, left unchanged, or aliased.

Ideate

  • HMW: How might we get students to predict a demo’s output before running it, instead of reading the result after the fact?
  • Activity: Students predict-then-run paired demos (reassign vs. mutate), then write a method that mutates and one that returns a new object.

Prototype

The first version used one combined demo: one Shape, mutated and then reassigned in the same method, with students predicting both outcomes at once.

Test

Mixing both outcomes in one method made it hard to tell which line caused which result, so the demo was split into separate examples. Predictions got noticeably more accurate.


3. College Board Requirements

This lesson addresses the following AP CSA Essential Knowledge statements:

  • 3.6.A.1 - When an object reference is passed to a method, the parameter gets a copy of that reference, not a new copy of the object. If the object is mutable, the method can use the reference to change it.
  • 3.6.A.2 - When a method returns an object reference, the reference itself is returned, not a reference to a new copy of the object.
  • 3.6.A.3 - A method can only access the private data of a parameter when the parameter is the same type as the method’s own class.

“When an argument is an object reference, the parameter is initialized with a copy of that reference; it does not create a new independent copy of the object.”

  • College Board AP CSA CED, p. 87

4. Lesson Plan

Learning Objective: Trace how object references move into and out of methods, and predict whether the caller’s object is mutated, left unchanged, or aliased.

Success Criteria: You can predict a demo’s output before running it and explain it with the words reference, mutate, reassign, and alias.

Tech Talk (5 minutes)

Think of a shared Google Doc. Sending someone the link shares a reference, not a copy. If they edit the doc, you see the edit next time you open it - you’re both looking at the same document.

But if they open a brand-new blank doc and type there, your doc is untouched. They just started looking at something else.

Java objects work the same way. A variable holding an object doesn’t hold the object itself - it holds a reference to it, like a link. Passing that variable into a method passes a copy of the link, not a copy of the document.

Code Runner Challenge

Try running the code below and observe what happens when two variables share one object:

Code Runner Challenge

Run this and observe the output. Then think: why does printing s show the change made through alias?

View IPYNB Source
// CODE_RUNNER: Run this and observe the output. Then think: why does printing s show the change made through alias?

class Shape {
    private String name;
    private int length, width;

    public Shape(String name, int length, int width) {
        this.name = name;
        this.length = length;
        this.width = width;
    }

    public int get_width() { return width; }
    public void set_width(int w) { width = w; }
    public void print_shape() { System.out.println(name + ": length=" + length + " width=" + width); }
}

public class Main {
    public static void main(String[] args) {
        Shape s = new Shape("square", 4, 4);
        Shape alias = s;       // a second link to the same object
        alias.set_width(99);
        s.print_shape();       // square: length=4 width=99
    }
}
Main.main(null);
Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

5. Code Examples

A. Simple - reassigning does not reach the caller

s = new Shape(...) only moves the method’s copy of the reference, so rect still points at the rectangle.

class Shape {
    private String name;
    private int length, width;

    public Shape(String name, int length, int width) {
        this.name = name;
        this.length = length;
        this.width = width;
    }

    public int get_width() { return width; }
    public void set_width(int w) { width = w; }
    public void print_shape() { System.out.println(name + ": length=" + length + " width=" + width); }
}

public class Main {
    public static void replaceShape(Shape s) {
        s = new Shape("replacement", 1, 1); // only the local copy moves
    }

    public static void main(String[] args) {
        Shape rect = new Shape("rectangle", 10, 5);
        replaceShape(rect);
        rect.print_shape();   // rectangle: length=10 width=5
    }
}
Main.main(null);

B. Intermediate - mutating reaches the caller

Calling a setter through the parameter changes the one shared object, so the caller sees it after the method returns.

class Shape {
    private String name;
    private int length, width;

    public Shape(String name, int length, int width) {
        this.name = name;
        this.length = length;
        this.width = width;
    }

    public int get_width() { return width; }
    public void set_width(int w) { width = w; }
    public void print_shape() { System.out.println(name + ": length=" + length + " width=" + width); }
}

public class Main {
    public static void doubleWidth(Shape s) {
        s.set_width(s.get_width() * 2); // changes the shared object
    }

    public static void main(String[] args) {
        Shape rect = new Shape("rectangle", 10, 5);
        doubleWidth(rect);
        rect.print_shape();   // rectangle: length=10 width=10
    }
}
Main.main(null);

C. Complex - returning a reference creates an alias

A method that returns one of its parameters hands back the same reference, so the result and the original are the same object.

class Shape {
    private String name;
    private int length, width;

    public Shape(String name, int length, int width) {
        this.name = name;
        this.length = length;
        this.width = width;
    }

    public int get_width() { return width; }
    public void set_width(int w) { width = w; }
    public void print_shape() { System.out.println(name + ": length=" + length + " width=" + width); }
}

public class Main {
    public static Shape wider(Shape a, Shape b) {
        if (a.get_width() >= b.get_width()) {
            return a;   // the same reference, not a copy
        }
        return b;
    }

    public static void main(String[] args) {
        Shape square = new Shape("square", 4, 4);
        Shape triangle = new Shape("triangle", 3, 3);
        Shape big = wider(square, triangle);
        System.out.println(big == square);   // true
        big.set_width(99);
        square.print_shape();   // square: length=4 width=99
    }
}
Main.main(null);

6. Hacks & Practice Tasks

Submission Safety Rules (Read First)

  • Only use Java - no CSS, no HTML.
  • Do not rename Shape or its fields and methods.
  • Make sure your code runs and prints the expected output before submitting.

Popcorn Hack (In-Class)

Task: Fill in growShape so it mutates the Shape it is given - add 5 to its length and width using the getters and setters. Hit Run - you should see: rectangle: length=15 width=10

Code Runner Challenge

Fill in growShape so it adds 5 to the length and width. Hit Run - you should see: rectangle: length=15 width=10

View IPYNB Source
// CODE_RUNNER: Fill in growShape so it adds 5 to the length and width. Hit Run - you should see: rectangle: length=15 width=10

class Shape {
    private String name;
    private int length, width;

    public Shape(String name, int length, int width) {
        this.name = name;
        this.length = length;
        this.width = width;
    }

    public int get_length() { return length; }
    public int get_width() { return width; }
    public void set_length(int l) { length = l; }
    public void set_width(int w) { width = w; }
    public void print_shape() { System.out.println(name + ": length=" + length + " width=" + width); }
}

public class Main {
    public static void growShape(Shape s) {
        // add 5 to s's length and width here

    }

    public static void main(String[] args) {
        Shape rect = new Shape("rectangle", 10, 5);
        growShape(rect);
        rect.print_shape();
    }
}
Main.main(null);
Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Homework Hack

Task: Fill in combine so it returns a brand-new Shape that joins the two names with - and adds their lengths and widths. Changing the result must not change either original.

Expected output:

square-triangle: length=7 width=7
square: length=4 width=4
triangle: length=3 width=3

Code Runner Challenge

Fill in combine so it returns a new Shape. Hit Run and check all three lines match the expected output.

View IPYNB Source
// CODE_RUNNER: Fill in combine so it returns a new Shape. Hit Run and check all three lines match the expected output.

class Shape {
    private String name;
    private int length, width;

    public Shape(String name, int length, int width) {
        this.name = name;
        this.length = length;
        this.width = width;
    }

    public String get_name() { return name; }
    public int get_length() { return length; }
    public int get_width() { return width; }
    public void set_width(int w) { width = w; }
    public void print_shape() { System.out.println(name + ": length=" + length + " width=" + width); }
}

public class Main {
    public static Shape combine(Shape s1, Shape s2) {
        // return a NEW Shape: names joined with "-", lengths added, widths added
        return null;
    }

    public static void main(String[] args) {
        Shape a = new Shape("square", 4, 4);
        Shape b = new Shape("triangle", 3, 3);
        Shape result = combine(a, b);
        if (result == null) {
            System.out.println("combine returned null - write it so it returns a new Shape");
            return;
        }
        result.print_shape();
        result.set_width(999);   // must NOT change a or b
        a.print_shape();
        b.print_shape();
    }
}
Main.main(null);
Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

7. Lesson Revisions


8. Feedback Evidence

No feedback collected yet.


9. References

College Board. (2025). AP Computer Science A course and exam description [Effective fall 2025]. https://apcentral.collegeboard.org/media/pdf/ap-computer-science-a-course-and-exam-description-effective-fall-2025.pdf

Oracle. (n.d.). Passing information to a method or a constructor. Oracle Java Tutorials. https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html