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:
myDoginmain()points to Heap address@0x100(name: "Buddy").- Inside
modifyDog(Dog d): parameterdis initialized with a copy of address@0x100. d.name = "Max"changes the string inside object at@0x100.d = new Dog("Charlie")allocates a new Heap object at@0x200and assigns@0x200tod.- When
modifyDogexits, parameterdis popped from the stack.myDoginmain()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.