AP® Computer Science A review sheet from Aim for Five (aimforfive.com/csa/units/3/3-6)
Unit 3 · Topic 3.6
3.6 Methods: Passing and Returning References of an Object
When an object is passed to a method or returned from one, what moves around is a reference, not a copy of the object. This topic shows exactly what a method can and can't change through a reference, and when a method may use another object's private data.
Key terms
- object reference
- pass by value
- mutable object
- returning a reference
Passing a reference
When the argument is an object, the parameter gets a copy of the reference. The method doesn't get its own copy of the object. Both the caller's variable and the parameter point to the same object.
That has two consequences, and you need both:
- If the method calls a mutator on the parameter, the original object changes, and the caller sees the change.
- If the method assigns a new object to the parameter, only the parameter changes. The caller's variable still refers to the original object.
Seeing both cases
public static void reset(Account a)
{
a = new Account(0);
}
public static void drain(Account a)
{
a.transferTo(new Account(0), a.getBalance());
}
Here reset points its own parameter at a new account and then ends, so the caller's account is untouched. drain uses the reference to move all the money out, so the caller's account really does change.
Good practice is not to change a mutable object passed in as a parameter unless the method's description says to.
Draw it out
For tracing questions, draw each object as a box with its instance variables inside, and each variable as a small box with an arrow pointing to an object. Passing an object to a method draws a new arrow from the parameter to the same box. Calling a mutator changes what's written inside a box. Assigning a new object to a variable moves only that variable's arrow. When the method ends, its parameter arrows disappear, but every change made inside the boxes stays.
Returning a reference
When a method returns an object, it returns a reference to it, not a new copy. If a getter returns a reference to a mutable instance variable, the caller can use it to change that object's state from outside the class.
Private access within the same class
Normally you can't touch another object's private instance variables. There's one exception: inside a class's own code, you can use the private data and methods of any parameter whose type is that same class. Encapsulation works class by class, not object by object.
public class Account
{
private int balance;
public Account(int start)
{
balance = start;
}
public void transferTo(Account other, int amount)
{
balance -= amount;
other.balance += amount;
}
public int getBalance()
{
return balance;
}
}
transferTo can write other.balance because other is also an Account. A method in some other class couldn't.
Worked examples
Try each one yourself first, then open the solution.
- Example 1
Changing an object through a parameter
Using the
Accountclass above, what does this code print?Account mine = new Account(100); Account yours = new Account(20); mine.transferTo(yours, 30); System.out.println(mine.getBalance() + " " + yours.getBalance());Show the solutionHide the solution
- Step 1:
minestarts with 100 andyourswith 20. - Step 2:
mine.transferTo(yours, 30)runs withbalancemeaningmine's balance andotherreferring to the same object asyours. - Step 3:
mine's balance becomes 70.other.balance += 30changes the objectyoursrefers to, so its balance becomes 50.
Answer: It prints
70 50. - Step 1:
- Example 2
Reassigning versus mutating
Using the methods
resetanddrainshown above, what does this code print?Account acct = new Account(40); reset(acct); System.out.println(acct.getBalance()); drain(acct); System.out.println(acct.getBalance());Show the solutionHide the solution
- Step 1:
reset(acct): the parameterastarts as a copy ofacct's reference. Thena = new Account(0)pointsaat a different object.acctstill refers to the original account, which still holds 40. - Step 2:
drain(acct):arefers to the same account asacct, anda.transferTo(...)moves all 40 out of it. That changes the original object.
Answer: Two lines:
40, then0. - Step 1:
- Example 3
Returning a reference
Using
Accountfrom above,Teamreturns its own private account:public class Team { private Account fund; public Team() { fund = new Account(500); } public Account getFund() { return fund; } }What does this code print?Team t = new Team(); Account f = t.getFund(); f.transferTo(new Account(0), 200); System.out.println(t.getFund().getBalance());Show the solutionHide the solution
- Step 1:
getFund()returns a reference to the team's ownAccountobject, not a copy. - Step 2:
fand the team'sfundnow refer to the same account. - Step 3: Transferring 200 out through
fchanges that shared account to 300, so the team's fund is 300.
Answer: It prints
300. - Step 1:
Common mistakes
- Thinking a method gets its own copy of an object argument. It gets a copy of the reference, so both refer to one object.
- Thinking that assigning a new object to a parameter changes the caller's variable. It doesn't.
- Thinking a getter that returns an object hands back a safe copy. It returns a reference to the same object.
On the exam
- Tracing questions often pass an object to a method that both mutates it and reassigns the parameter. Draw a box for each object and arrows for each variable, and move only the arrows when a variable is reassigned.
Connected topics
Videos
Check yourself
4 questions on 3.6 Methods: Passing and Returning References of an Object. Pick an answer to see if you got it, and why.
public class Box
{
private int value;
public Box(int v)
{
value = v;
}
public int getValue()
{
return value;
}
public void setValue(int v)
{
value = v;
}
}Consider the following methods, which appear in a class other than Box.public static void reset(Box b)
{
b.setValue(0);
}
public static void replace(Box b)
{
b = new Box(99);
}What is printed as a result of executing the following code segment, which appears in the same class as reset and replace?Box a = new Box(5);
replace(a);
System.out.print(a.getValue() + " ");
reset(a);
System.out.print(a.getValue());
Consider the following methods, which appear in a class other than Box.public static void swapRefs(Box a, Box b)
{
Box temp = a;
a = b;
b = temp;
}
public static void swapValues(Box a, Box b)
{
int temp = a.getValue();
a.setValue(b.getValue());
b.setValue(temp);
}What is printed as a result of executing the following code segment, which appears in the same class as the two methods?Box x = new Box(1);
Box y = new Box(2);
swapRefs(x, y);
System.out.print(x.getValue() + " " + y.getValue() + " ");
swapValues(x, y);
System.out.print(x.getValue() + " " + y.getValue());
Consider the following classes.public class Player
{
private int number;
public Player(int n)
{
number = n;
}
public int getNumber()
{
return number;
}
public void setNumber(int n)
{
number = n;
}
}
public class Team
{
private Player captain;
public Team(int captainNumber)
{
captain = new Player(captainNumber);
}
public Player getCaptain()
{
return captain;
}
}What is printed as a result of executing the following code segment?Team t = new Team(10);
Player p = t.getCaptain();
p.setNumber(7);
System.out.println(t.getCaptain().getNumber());
Consider the following class.public class Money
{
private int cents;
public Money(int c)
{
cents = c;
}
public int getCents()
{
return cents;
}
public boolean moreThan(Money other)
{
return cents > other.cents;
}
}A different class, Wallet, has a method with a parameter Money m. Wallet doesn't declare any variable named cents. Which of the following statements compiles if it appears in that Wallet method?
0 of 4 answered