Skip to main content

2.5 Methods & Pass-by-Value Semantics

← Back to Chapter 2: Java Overview & Memory Model

One of the most widely misunderstood concepts in Java is its parameter-passing mechanism. Java is strictly 100% Pass-by-Value at all times.


1. The Definitive Proof: References are Passed by Value​

When passing an object into a method, you do not pass the actual object, nor do you pass an alias to the reference variable. Instead, you pass a copy of the 64-bit reference address.

public class ValueTest {
static class Dog {
String name;
Dog(String name) { this.name = name; }
}

public static void modifyDog(Dog d) {
// Step 1: Mutating state via the copied reference affects the original Heap object
d.name = "Max";

// Step 2: Reassigning the local parameter 'd' to a NEW object
d = new Dog("Charlie");
// This only redirects the local copy 'd'!
}

public static void main(String[] args) {
Dog myDog = new Dog("Buddy");
modifyDog(myDog);
System.out.println(myDog.name); // Prints "Max", NOT "Charlie"!
}
}

Memory Trace:​

  1. myDog in main() points to Heap address @0x100 (name: "Buddy").
  2. Inside modifyDog(Dog d): parameter d is initialized with a copy of address @0x100.
  3. d.name = "Max" changes the string inside object at @0x100.
  4. d = new Dog("Charlie") allocates a new Heap object at @0x200 and assigns @0x200 to d.
  5. When modifyDog exits, parameter d is popped from the stack. myDog in main() still points strictly to @0x100.

2. Varargs (Variable-Length Arguments)​

Varargs (...) allows a method to accept zero or more arguments of a specified type. Under the hood, the compiler packages arguments into an array:

public static int sum(int... numbers) {
int total = 0;
for (int n : numbers) { // numbers is an int[]
total += n;
}
return total;
}
Varargs Rule

Varargs must always be the last parameter in a method signature (void log(String tag, Object... args)). A method cannot declare more than one varargs parameter.