Memra

Pass-by-value: the most-misunderstood Java rule

Java is always pass-by-value — even for objects. What that means precisely.

Java is always pass-by-value

When you call a method, the value of each argument is copied into the parameter. For primitives, that's the numeric value. For objects, that's the reference (memory address) — not the object itself.

Primitive — the caller's variable is unaffected:

static void doubleIt(int n) { n = n * 2; }

int x = 5;
doubleIt(x);
System.out.println(x); // 5 — unchanged; doubleIt got a copy

Reference — the object is shared, but reassigning the parameter doesn't affect the caller:

static void clear(StringBuilder sb) {
    sb.setLength(0);  // mutates the shared object — CALLER SEES THIS
}

static void replace(StringBuilder sb) {
    sb = new StringBuilder("new"); // reassigns the local copy — CALLER DOES NOT see this
}

StringBuilder buf = new StringBuilder("hello");
clear(buf);
System.out.println(buf);   // "" — mutation is visible

buf = new StringBuilder("hello");
replace(buf);
System.out.println(buf);   // "hello" — reassignment not visible

The key insight: mutating the object through the reference propagates (caller and method share the same object), but reassigning the parameter variable only changes the local copy — the caller's reference is untouched.

NORMAL ~/memra/learn/java-from-zero/pass-by-value utf-8 LF