Pass by value or Pass by Reference?
Short answer: Java is always pass-by-value.
What trips people up is what the “value” is:
- For primitives (
int
,double
,boolean
, …): the value is the actual number/bit pattern. You get a copy → changes inside the method don’t affect the caller. - For objects/arrays: the value is a copy of the reference (a pointer). You can use that reference to mutate the same object, but you cannot change which object the caller’s variable refers to.
Tiny proofs
1) Primitives don’t change
void inc(int x) { x++; }
int a = 5;
inc(a);
System.out.println(a); // 5 (unchanged)
2) Object’s state can change, but the caller’s reference can’t be redirected
class Box { int v; }
void bump(Box b) { b.v++; } // mutate same object
void replace(Box b) { b = new Box(); b.v = 99; } // reassign local copy of reference
Box b = new Box();
b.v = 1;
bump(b);
System.out.println(b.v); // 2 (mutated)
replace(b);
System.out.println(b.v); // 2 (still the same object; reassignment didn't escape)
3) “Swap” fails (classic)
void swap(Box x, Box y) { Box tmp = x; x = y; y = tmp; }
Box a = new Box(), b = new Box();
swap(a, b);
// a and b still refer to the originals
Notes
-
Arrays behave like objects:
modify(arr[i])
changes elements;arr = new int[10]
inside a method won’t change the caller’s reference. -
String and wrapper types (
Integer
, etc.) are immutable: you can’t change their contents; reassigning the parameter just changes the local copy. - Marking a parameter
final
only prevents reassignment inside the method; it doesn’t change pass-by-value semantics.
Mental model: parameters are copies. For objects, it’s a copy of the reference, not a reference to the reference.