Understanding Pass‑by‑Value and the Illusion of Pass‑by‑Reference in Java
This article explains that Java fundamentally uses pass‑by‑value for method parameters, distinguishing between primitive value types stored on the stack and reference types whose references are passed, and demonstrates the behavior with code examples that clarify why apparent reference passing is actually passing a copy of the reference.
Java only supports pass‑by‑value; method arguments are always passed as copies, not as the original variables.
1. Value Types
Value types correspond to Java's eight primitive data types: byte, short, int, long, float, double, char, boolean . These values are stored directly on the JVM stack when assigned.
From the JVM perspective, a value type generates its value directly in the stack.
2. Reference Types
Reference types include classes, interfaces, arrays, strings, and wrapper classes (e.g., Integer , Double ). When a reference type is created, a reference is stored on the stack while the actual object resides on the heap.
3. Pass‑by‑Value
Pass‑by‑Value means the method receives a copy of the original argument; modifying the copy does not affect the original.
public class PassTest {
public static void main(String[] args) {
int age = 18;
System.out.println("调用方法前:" + age);
intTest(age);
System.out.println("调用方法后:" + age);
}
private static void intTest(int age) {
age = 30;
System.out.println("方法中修改为:" + age);
}
}Output:
调用方法前:18 方法中修改为:30 调用方法后:18
4. Simulated Pass‑by‑Reference
When an array (a reference type) is passed, the method receives a copy of the reference, so modifications to the array's contents affect the original object.
public class PassTest {
public static void main(String[] args) {
char[] name = {'磊','哥'};
System.out.println("调用方法前:" + new String(name));
paramTest(name);
System.out.println("调用方法后:" + new String(name));
}
private static void paramTest(char[] n) {
n[1] = '神';
System.out.println("方法中修改为:" + new String(n));
}
}Output:
调用方法前:磊哥 方法中修改为:磊神 调用方法后:磊神
This appears to be pass‑by‑reference, but it is actually passing a copy of the reference.
5. Why It Is Still Pass‑by‑Value
If the method reassigns the parameter to a new object, the original reference remains unchanged, demonstrating true pass‑by‑value.
public class PassByValue {
public static void main(String[] args) {
char[] name = {'磊','哥'};
System.out.println("调用方法前:" + new String(name));
paramTest(name);
System.out.println("调用方法后:" + new String(name));
}
private static void paramTest(char[] n) {
n = new char[2]; // add this line
n[1] = '神';
System.out.println("方法中修改为:" + new String(n));
}
}Output:
调用方法前:磊哥 方法中修改为:神 调用方法后:磊哥
Because the method created a new array, the original array in main was not affected, confirming that Java only passes copies.
Summary
Java uses pass‑by‑value for all method arguments; primitives are copied directly, while references are copied as references. Objects and arrays live on the heap, with their references stored on the stack, which explains why modifications to mutable objects appear to be pass‑by‑reference.
Full-Stack Internet Architecture
Introducing full-stack Internet architecture technologies centered on Java
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.