Does Java pass by reference or pass by value?

The question of whether Java is pass-by-reference or pass-by-value is a common source of confusion among Java developers. To understand this, we need to clarify what pass-by-reference and pass-by-value mean.

Understanding Pass-by-Value and Pass-by-Reference

  1. Pass-by-value: A copy of the argument's value is passed to the method. Any changes within the method only affect the copy, not the original variable.
  2. Pass-by-reference: A reference (memory address) to the original variable is passed to the method. Changes within the method modify the original variable.

Key Points:

  1. Java always passes a copy of the value (primitive value or object reference).
  2. For primitives, the copy is independent, so changes within the method don't affect the original variable.
  3. For objects, the reference copy still points to the same object, so changes through the reference modify the original object.

Java is strictly pass-by-value. However, this can be misleading due to the way objects and references work in Java.

Let's break it down with examples:

Primitive Data Types (Pass-by-Value in True Sense)

Primitive data types like int, char, and boolean store their actual values in variables. In Java:

public class PassByValueExample { public static void main(String[] args) { int x = 10; System.out.println("Before method call: " + x); modifyValue(x); System.out.println("After method call: " + x); } public static void modifyValue(int num) { num = 20; } }

In this example, x is passed to the modifyValue method. However, any changes made to num inside the method do not affect the value of x outside the method. This demonstrates pass-by-value behavior.

Object References (Pass-by-Value with a Twist)

Objects reside in the heap, and variables hold references (memory addresses) to those objects. In Java:

public class PassByValueObjectExample { public static void main(String[] args) { Person person = new Person("Alice"); System.out.println("Before method call: " + person.getName()); modifyObject(person); System.out.println("After method call: " + person.getName()); } public static void modifyObject(Person p) { p.setName("Bob"); } } class Person { private String name; public Person(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }

In this example, an instance of the Person class is created and passed to the modifyObject method. Even though the reference to the Person object is passed, any changes made to the object's properties (like the name) inside the method affect the original object outside the method. However, it's important to understand that what's being passed by value is the reference to the object, not the object itself. So, technically, Java is still pass-by-value.

Conclusion

Java is pass-by-value, but when dealing with objects, what's passed by value is the reference to the object, not the object itself. This can sometimes lead to confusion, especially for those coming from languages that support true pass-by-reference like C++.