AP® Computer Science A · Unit 3 · Topic 3.6
Returning a Reference and Leaking Private State
When a getter returns a private array directly, it hands outside code a reference to the exact same array sitting inside the object, so anyone can reach in and change it. Returning a copy keeps the original safe.
Marking a field private is supposed to mean only the class's own methods can touch it. But private only blocks outside code from writing object.scores directly by name. It says nothing about what happens once you hand out a reference to that field through a method. If getScores() does return scores;, the caller doesn't get a copy of the data, it gets the actual memory address of your internal array. Now two variables point at the same array: your private field, and whatever variable the caller stored the return value in.
Once that reference is out, the caller can write int[] s = obj.getScores(); s[0] = 9999; and that line changes the real field, because s and scores are names for the same array. No private modifier stops this, because the caller never touched the field itself, only the array it points to. This is the core trap of reference types: copying a reference copies the address, not the data, so both copies control the same object.
The fix is to return a new array built from the original: something like a loop or Arrays.copyOf that copies each value into a fresh array, then returns that. Now the caller holds a reference to a brand new array, and mutating it leaves your private field untouched. This matters less for a getName() returning a String, because String objects can't be changed after creation. Handing out a reference to an immutable object is safe, since there is no method that lets anyone alter its characters. That contrast, mutable array versus immutable String, is exactly why Unit 3 keeps circling back to what a reference actually lets you do.
Key terms
- reference
- A variable's stored value that points to where an object actually lives in memory, not the object's data itself.
- mutable
- Capable of having its internal data changed after creation, as arrays are.
- immutable
- Unable to be changed after creation, as String objects are in Java.
- encapsulation
- Hiding an object's internal data so it can only be changed through the class's own controlled methods.
- defensive copy
- A fresh duplicate of a mutable field returned instead of the original, so outside code can't alter the real data.
Watch it explained
- How it worksHow does a returned reference give outside code a direct line into an object's data?
- Worked exampleTrace getScores returning the private array and an outside caller writing straight into it.
- How it worksHow does returning a copy of the array close the hole the bare reference opened?
- Common mistakeWhy isn't returning a String field a leak the way returning an array field is?
Check yourself
End of topic.