Why Java Uses Only Pass‑by‑Value (No Pass‑by‑Reference) Explained
The article clarifies that Java always uses pass‑by‑value—whether for primitive types or object references—by showing how values are copied, how reference addresses are passed as values, and why common misconceptions about reference passing arise.
Java’s Parameter‑Passing Mechanism
Java always uses pass‑by‑value. The value that is passed can be either a primitive value or the value of an object reference (the memory address). No true pass‑by‑reference exists.
Pass‑by‑Value Definition
Pass‑by‑Value : a copy of the argument’s value is supplied to the method. Modifying the copy does not affect the original variable.
Pass‑by‑Reference : the method receives the variable itself (its memory address) and can modify the original directly. Java does not employ this mechanism.
Scenario 1 – Primitive Types
When a primitive is passed, Java copies the primitive value and supplies that copy to the callee.
public class ValuePassTest {
public static void main(String[] args) {
int num = 10;
System.out.println("Before call, num = " + num); // 10
changeNum(num);
System.out.println("After call, num = " + num); // still 10
}
public static void changeNum(int num) {
num = 20; // modifies the copy
System.out.println("Inside method, num = " + num); // 20
}
}`changeNum` receives a copy of the value 10. The two `num` variables occupy different memory locations, so the assignment inside the method does not affect the original variable. This is classic value passing.
Scenario 2 – Reference Types (Objects)
When an object is passed, Java copies the reference value (the address) and passes that copy.
class User {
String name;
int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
}
public class ValuePassTest {
public static void main(String[] args) {
User user = new User("Zhang San", 20);
System.out.println("Before call, age = " + user.age); // 20
changeUserAge(user);
System.out.println("After call, age = " + user.age); // 30
}
public static void changeUserAge(User userParam) {
userParam.age = 30; // modifies the object's field
System.out.println("Inside method, age = " + userParam.age); // 30
}
}Steps:
`User user = new User("Zhang San", 20);` creates an object and stores its address (e.g., 0x123456) in `user`.
Calling `changeUserAge(user)` copies that address value and passes it to `userParam`.
Both `user` and `userParam` now hold the same address, therefore refer to the same `User` instance.
`userParam.age = 30` changes the field of the shared object; the change is visible through `user` as well.
The method does **not** change the original reference variable (`user`); it only mutates the object that the copied address points to.
Test – Reassigning the Parameter Reference
If Java used true reference passing, reassigning the parameter to a new object would also change the caller’s variable. The following test shows that this does not happen:
public class ValuePassTest {
public static void main(String[] args) {
User user = new User("Zhang San", 20);
System.out.println("Before call, name = " + user.name); // 张三
changeUserReference(user);
System.out.println("After call, name = " + user.name); // still 张三
}
public static void changeUserReference(User userParam) {
// Point to a new User object
userParam = new User("Li Si", 25);
System.out.println("Inside method, name = " + userParam.name); // 李四
}
}The output confirms that `userParam` now points to a new object, while the original `user` in `main` still points to the original object. Hence only the address value was copied.
Root Cause of the Misconception
Developers often conflate “object reference” with “reference passing”. In Java, the argument passed is the **value of the reference** (the address). Because the address is a value, the mechanism remains pass‑by‑value. An analogy: a key (the reference value) opens a house (the object). Giving a copy of the key lets the recipient open the same house and rearrange furniture (modify fields), but the original key still opens the same house. Replacing the copy with a different key does not affect the original key.
Common Misconceptions
“Passing an object is reference passing.” Incorrect – the passed value is the reference address, which is itself a value.
“If a method changes an object’s property, the language must use reference passing.” Incorrect – the change occurs because the copied address points to the same object, not because the reference itself was passed.
“Arrays and collections are passed by reference.” Incorrect – arrays and collections are reference types, so their reference addresses are copied and passed as values. Modifying an element changes the shared object; reassigning the array variable does not affect the caller’s variable.
Key Takeaway
Java’s parameter‑passing rule is uniform:
For primitives, the primitive value is copied.
For reference types, the reference (memory address) is copied.
The method can mutate the object reachable via the copied address, but it cannot reassign the caller’s variable. Understanding this eliminates confusion about why certain parameter modifications are not reflected in the caller and prevents related bugs.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Tech Workshop
Focused on Java backend technologies, sharing fundamentals, multithreading, JVM, the Spring ecosystem, microservices, distributed systems, high concurrency, source‑code analysis, and practical experience. Continuously delivers high‑quality original content, interview guides, and learning roadmaps to help Java developers progress from beginner to advanced, enhancing technical skills and core competitiveness.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
