Java is strictly pass-by-value. However, the behavior can be confusing when dealing with objects. Here’s a breakdown:
1. Primitive Types (e.g., int
, double
, boolean
)
Primitives are passed by value:
- A copy of the value is passed to the method.
- Modifying the parameter inside the method does not affect the original variable.
Example:
java
void increment(int x) {
x++; // Modifies the copy
}
int num = 5;
increment(num);
System.out.println(num); // Output: 5 (unchanged)
2. Object Types (e.g., String
, List
, custom classes)
Object references are passed by value:
- A copy of the reference (memory address) to the object is passed.
- The method and caller share access to the same object in memory.
- Changes to the object’s state (e.g., modifying fields) are visible outside the method.
- Reassigning the parameter’s reference (e.g.,
obj = new Object()
) does not affect the caller’s reference.
Example:
java
class Dog {
String name;
Dog(String name) { this.name = name; }
}
void modifyDog(Dog d) {
d.name = "Max"; // Changes the shared object’s state
d = new Dog("Buddy"); // Reassigns the local copy of the reference
}
Dog myDog = new Dog("Rex");
modifyDog(myDog);
System.out.println(myDog.name); // Output: "Max" (not "Buddy")
Key Takeaways
- Primitives: Copies of values are passed.
- Objects: Copies of references (pointers) are passed.
- Java never passes the actual object itself.
Why It Feels Like “Pass-by-Reference” Sometimes
If a method modifies an object’s internal state (e.g., updating a list), those changes persist outside the method because the copied reference still points to the same object. However, this is not true pass-by-reference (where the caller’s variable itself could be redirected to a new object).
Example: Swapping Fails
java
void swap(Integer a, Integer b) {
Integer temp = a;
a = b; // Only swaps local copies
b = temp;
}
Integer x = 1, y = 2;
swap(x, y);
System.out.println(x + ", " + y); // Output: 1, 2 (no swap)
This fails because a
and b
are copies of references, not the actual variables x
and y
.
Conclusion
Java uses pass-by-value exclusively:
- For primitives, the value itself is copied.
- For objects, the reference (pointer) is copied, not the object.
This design ensures clarity and avoids unintended side effects of true pass-by-reference.