Mutability & references — cheat sheet
From: fundamentals/03-mutability.md.
Value types vs reference types
- Primitives (
int, etc.) andStringare copied by value: a local variable is an independent copy. Reassigning a copy inside a function never affects the caller's variable — you must return the new value and reassign it yourself. - A variable holding a class instance actually holds a reference (pointer) to that instance, not the instance itself.
otherPerson = personcopies the reference — both variables now point at the same object.- Mutating a field through one reference (
person.age = 21) is visible through every other reference to that same instance (otherPerson.ageis also 21). - Passing an object into a method passes the reference, not a copy — mutating its fields inside the method is visible to the caller after the call returns (unlike passing an
int, where the callee's copy is thrown away).
Shared mutable state (why it's dangerous)
Two variables/parameters referencing the same mutable object is fine — until one piece of code mutates it expecting only local effects, while another piece of code still depends on the original state.
Canonical example (the "car race" bug): a list of race results, ordered by finish position, is used both to display all participants and to congratulate the winner (list.get(0)). Sorting that same list alphabetically for display purposes — via Collections.sort(participants) — mutates it in place, so the "winner" lookup afterward now points at the wrong person. The fix is to sort a copy (new ArrayList<>(participants)), leaving the original (and whatever else depends on it) untouched.
This is the pattern to recognize in an interview: a bug caused not by wrong logic in either function individually, but by two functions unknowingly sharing one mutable object.
Lists: mutable vs immutable
new ArrayList<>(...)— mutable,.add()/.remove()work.List.of(...)— immutable,.add()/.remove()throwUnsupportedOperationExceptionat runtime (not a compile error).- To get a mutable working copy of an immutable list:
new ArrayList<>(immutableList).
General guidance
- Default to immutable data where practical; treat mutability as something you opt into when actually needed, not the default.
- A crash from an immutable structure is often preferable to silently wrong data — it points straight at the root cause instead of letting a bug propagate quietly.