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.

Back to blog

Leave a comment

Please note, comments need to be approved before they are published.