Introduction
One of the most frequently asked interview questions in Java is:
“Does Java use pass by value or pass by reference?”
The answer is Java is always pass by value. However, this creates confusion when it comes to object references. This article will clarify the difference between passing primitive types and object references, supported by code examples, diagrams, and best practices.
What is Pass by Value?
When you pass a variable to a method in Java, the method receives a copy of the value, not the original variable.
This means any changes made inside the method do not affect the original variable, unless the value is a reference to an object and you modify the object’s internal state.
Pass by Value with Primitive Types
Primitives (int, float, boolean, etc.) are stored directly in memory.
When passed to a method, their value is copied.
Example: Primitive Pass by Value
public class PrimitiveExample {
public static void modifyValue(int num) {
num = 50; // changes local copy only
}
public static void main(String[] args) {
int number = 10;
modifyValue(number);
System.out.println("Number after method call: " + number);
}
}
Output:
Number after method call: 10
The value 10
remains unchanged because only a copy was modified.
Pass by Value with Object References
When you pass an object to a method, the reference itself is passed by value.
- The method gets a copy of the reference pointing to the same object in heap memory.
- Modifying the object’s fields inside the method will affect the original object.
- Reassigning the reference inside the method does not affect the original reference.
Example: Object Reference Pass by Value
class Person {
String name;
}
public class ObjectExample {
public static void modifyPerson(Person p) {
p.name = "Alice"; // modifies the object’s state
p = new Person(); // reassigns local reference
p.name = "Bob";
}
public static void main(String[] args) {
Person person = new Person();
person.name = "John";
modifyPerson(person);
System.out.println("Person name after method call: " + person.name);
}
}
Output:
Person name after method call: Alice
The state of the object changes to "Alice" because both references pointed to the same object initially.
However, the reassignment to a new Person()
object inside the method does not affect the original reference.
Key Differences: Primitives vs Object References
Aspect | Primitive Types | Object References |
---|---|---|
What gets copied | Actual value | Memory address (reference) |
Can method modify value | No (only local copy is changed) | Yes (object’s state can be modified) |
Can method reassign var | No effect on original variable | No effect on original reference |
Common Mistakes and Misconceptions
-
“Java is pass by reference for objects.”
❌ Wrong. It’s pass by value of the reference. -
Reassigning object reference in method updates original object.
❌ Wrong. Only the internal state of the object can be updated, not the reference itself. -
Immutable objects like
String
behave the same as mutable ones.
✅ True, but you can’t modifyString
’s state, so it looks like primitives.
Best Practices
- For primitives, pass them directly if they are small in size.
- For large objects, avoid unintended side-effects by making defensive copies.
- Prefer immutable objects to avoid confusion with reference modifications.
Interview Relevance
- ✅ Commonly asked in Java interviews.
- ✅ Demonstrates understanding of Java memory model.
- ✅ Important for designing methods and APIs.
Java Version Relevance
- The behavior of pass-by-value has not changed across Java versions.
- Applies to all versions from Java 1.0 to Java 21+.
Summary
- Java is always pass by value.
- Primitives copy the actual value.
- Object references copy the memory address, allowing modification of the object’s state but not the reference.