One of the most important concepts to understand when working with Java methods is how arguments are passed to them. Beginners often hear the phrase “pass by reference” and assume Java works that way. It does not.
Java is strictly pass by value. The important part is understanding exactly what value is copied when the argument is a primitive and what value is copied when the argument is an object reference.
What Does Pass by Value Mean?
Pass by value means that when a method is invoked, Java gives the method a copy of the argument's value. Changes made to that parameter itself do not change the original variable used by the caller.
static void change(int number) {
number = 100;
}
int value = 50;
change(value);
System.out.println(value);
The output is:
50
Why? The method receives a copy of value. Changing the local parameter number changes only that copied value.
Remember: Java always passes a copy of a value to a method. Java does not pass variables themselves.
Pass by Value with Primitive Types
Primitive values such as int, double, char, and boolean are straightforward. The actual primitive value is copied into the method parameter.
static void update(int x) {
x = 200;
}
public static void main(String[] args) {
int number = 10;
update(number);
System.out.println(number);
}
The output is:
10
The variable number remains unchanged because x contains a separate copy of its value.
Visualizing Primitive Pass by Value
Suppose the caller contains:
int number = 25;
When this method is invoked:
change(number);
you can conceptually visualize the situation like this:
Caller:
number = 25
|
| copy of value
v
Method:
x = 25
If the method executes x = 100;, only the method's parameter changes.
Why the Original Primitive Does Not Change
static void change(int x) {
x = 500;
}
int value = 100;
change(value);
At the time of invocation, Java copies the value 100 into x. The assignment x = 500; replaces the value stored in the local parameter. It does not reach backward and modify the caller's variable.
Pass by Value with Objects
This is where many Java learners become confused. Java still uses pass by value when objects are involved.
The difference is that an object variable contains a reference value. Java copies that reference value when passing the argument to a method.
class Student {
String name;
}
static void changeName(Student student) {
student.name = "Rahul";
}
Student s = new Student();
s.name = "Anita";
changeName(s);
System.out.println(s.name);
The output is:
Rahul
This sometimes leads beginners to conclude that Java passed the object by reference. That conclusion is incorrect.
What Actually Happens with an Object?
The variable s contains a reference to a Student object. When the method is called, Java copies that reference into the parameter student.
Caller:
s
|
v
Student object
name = "Anita"
Method:
student
|
+----> same Student object
Both variables contain references that point to the same object. Therefore, changing the object's field through the copied reference is visible through the original reference.
Important: The reference itself is passed by value. The object is not passed by reference. The copied reference can still point to the same object.
Changing an Object's State
Consider another example:
class Account {
double balance;
}
static void deposit(Account account) {
account.balance += 500;
}
Account account = new Account();
account.balance = 1000;
deposit(account);
System.out.println(account.balance);
The output is:
1500.0
The method changed the state of the object that both references point to. This does not violate pass-by-value because the method received a copied reference value.
Reassigning an Object Parameter
Now consider a subtle but very important difference. What happens if the method assigns a completely different object to its parameter?
class Student {
String name;
}
static void replaceStudent(Student student) {
student = new Student();
student.name = "Rahul";
}
Student s = new Student();
s.name = "Anita";
replaceStudent(s);
System.out.println(s.name);
The output is:
Anita
Why did the original reference not change? Because the method only changed its local copy of the reference. The caller's variable s still points to the original object.
Object Mutation vs Reference Reassignment
| Operation | Effect on Caller |
|---|---|
| Change object field | Caller can observe the changed object state. |
| Modify object through a method | Caller can observe the modification. |
| Reassign method parameter | Caller reference does not change. |
| Assign a new object to parameter | Caller still points to its original object. |
A Practical Example
Consider a shopping cart:
class Cart {
int items;
}
static void addItem(Cart cart) {
cart.items++;
}
Cart cart = new Cart();
addItem(cart);
addItem(cart);
System.out.println(cart.items);
The output is:
2
The method receives a copied reference, but that reference points to the same Cart object. Therefore, modifications to the object's state are visible to the caller.
Can a Method Swap Two Primitive Variables?
A classic example demonstrates pass by value clearly.
static void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
int x = 10;
int y = 20;
swap(x, y);
System.out.println(x);
System.out.println(y);
The output remains:
10
20
The method swaps only its local copies of the values. The original variables are unaffected.
Why Java Does Not Use Traditional Pass by Reference
In a true pass-by-reference mechanism, a method receives direct access to the caller's variable itself and can replace what that variable refers to. Java does not provide this behavior for ordinary method parameters.
Instead, Java always copies the value. For primitives, that value is the primitive itself. For objects, that value is the reference pointing to the object.
Primitive vs Object Arguments
| Argument Type | What Is Copied? | Can Method Change Caller Variable? |
|---|---|---|
| int | Integer value | No |
| double | Decimal value | No |
| boolean | Boolean value | No |
| Object | Reference value | No, not the reference itself |
| Object state | Accessed through copied reference | Yes, the object's mutation can be observed |
Arrays Are Also Passed by Value
Arrays are objects in Java, so an array argument follows the same rule. The reference to the array is copied.
static void update(int[] numbers) {
numbers[0] = 999;
}
int[] values = {10, 20, 30};
update(values);
System.out.println(values[0]);
The output is 999 because both the caller and the method's parameter refer to the same array object.
However, reassigning the parameter does not replace the caller's array reference.
static void replace(int[] numbers) {
numbers = new int[] {100, 200, 300};
}
int[] values = {10, 20, 30};
replace(values);
System.out.println(values[0]);
The output is still 10 because only the local copy of the reference was reassigned.
Strings and Pass by Value
Strings are objects, but they are immutable. This creates another common source of confusion.
static void change(String text) {
text = "Java";
}
String message = "Hello";
change(message);
System.out.println(message);
The output is:
Hello
The method receives a copied reference. Assigning a new String to text changes only the local parameter. The original message variable remains unchanged.
Common Beginner Misconception
A very common statement is: “Java passes objects by reference.” This is technically incorrect.
The accurate statement is: “Java passes object references by value.”
This distinction may sound small, but it explains why a method can mutate an object's state while being unable to replace the caller's reference.
Memory trick: Java copies whatever value is stored in the variable. For an object variable, that stored value is a reference.
How to Explain Pass by Value in an Interview
A strong interview answer is: “Java is always pass by value. For primitive arguments, the primitive value is copied. For object arguments, the reference value is copied, so both the caller and method parameter can refer to the same object. Mutating that object can be visible to the caller, but reassigning the parameter does not change the caller's reference.”
Common Mistakes
- Saying Java uses pass by reference for objects.
- Confusing an object with the reference stored in an object variable.
- Expecting reassignment of a method parameter to replace the caller's variable.
- Assuming that changing an object's state means the object itself was passed by reference.
- Forgetting that arrays are objects and follow the same reference-value rule.
Best Practices
- Use clear method names that communicate whether a method modifies an object.
- Do not rely on confusing parameter reassignment to communicate changes to callers.
- Document methods that intentionally mutate objects when the behavior matters to the caller.
- Prefer immutable objects where appropriate when unexpected mutation could make code difficult to reason about.
- When explaining Java parameter passing, always distinguish between an object and its reference value.
Quick Revision
| Concept | Key Point |
|---|---|
| Java parameter passing | Java always uses pass by value. |
| Primitive argument | A copy of the primitive value is passed. |
| Object argument | A copy of the object reference is passed. |
| Object mutation | Changes to the shared object's state can be observed by the caller. |
| Reference reassignment | Changing the method parameter to point somewhere else does not change the caller's reference. |
| Array argument | An array reference is passed by value because arrays are objects. |
| Correct terminology | Java passes object references by value, not objects by reference. |
Pass by value becomes much easier once you stop thinking in terms of “objects versus primitives” and instead ask one simple question: what value is stored in the variable being passed? Java copies that value. Understanding this rule removes one of the most persistent sources of confusion in Java and prepares you for more advanced topics involving objects, collections, and recursive method calls.
