Back to Blog
Java

Why Java Is Pass by Value: Understanding References

java why java is pass by value: Understand why Java is pass by value, even for objects. Learn how references are copied and how to design methods that actually change...

Javapass by valuereferencesmethod argumentsobject references
Diagram showing a Java method call copying a object reference value into a parameter, illustrating pass-by-value behavior.

java why java is pass by value requires a clear understanding of the core syntax, runtime behavior, and practical implementation patterns demonstrated in the examples below.

The Core Question: What Does Pass by Value Mean in Java?

The phrase "Java is pass by value" often triggers a debate among developers. When you pass a variable to a method, Java copies the value stored in that variable into the method's parameter. For primitives, the value is the actual number or character. For objects, the value is a reference—the memory address of the object. That reference is copied, not the object itself. This is why Java is pass by value: the method receives a copy of the reference, and any reassignment to the parameter inside the method does not affect the original variable.

How Primitives Are Passed: A Copy of the Value

Consider this simple example:

public class PrimitivePassing { static void change(int x) { x = 10; } public static void main(String[] args) { int a = 5; change(a); System.out.println(a); // prints 5 } }

The variable a holds the value 5. When change(a) is called, Java copies 5 into the parameter x. Inside change, x is reassigned to 10, but a remains 5 because the method operates on a copy. This is straightforward pass by value.

How Object References Are Passed: A Copy of the Reference

Now consider an object:

class Point { int x; int y; Point(int x, int y) { this.x = x; this.y = y; } } public class ReferencePassing { static void move(Point p) { p.x = 100; p.y = 200; } public static void main(String[] args) { Point point = new Point(1, 2); move(point); System.out.println(point.x + ", " + point.y); // prints 100, 200 } }

The variable point holds a reference to a Point object. When move(point) is called, Java copies that reference into the parameter p. Both point and p now refer to the same object. Modifying p.x changes the same object that point refers to. This is why many developers mistakenly think objects are passed by reference. But the reference itself is passed by value—the copy of the reference still points to the same object.

Why the Classic Swap Method Fails

A common test to determine pass by value vs reference is a swap method:

public class SwapExample { static void swap(Integer a, Integer b) { Integer temp = a; a = b; b = temp; } public static void main(String[] args) { Integer x = 1; Integer y = 2; swap(x, y); System.out.println(x + " " + y); // prints 1 2 } }

The swap does not work because a and b are local copies of the references. Reassigning them only changes the local variables, not the original variables x and y. The objects themselves are not modified; only the local references are swapped. To actually swap values, you would need to modify the objects' internal state, or return a new pair.

Modifying Object State Through a Reference

When you want a method to change an object, you must call methods on the reference or directly access its fields, not reassign the parameter. For example:

class MutablePoint { int x; int y; } public class ModifyObject { static void translate(MutablePoint p, int dx, int dy) { p.x += dx; p.y += dy; } public static void main(String[] args) { MutablePoint p = new MutablePoint(); p.x = 0; p.y = 0; translate(p, 5, 10); System.out.println(p.x + ", " + p.y); // prints 5, 10 } }

Here, translate modifies the fields of the object that p refers to. Because the reference is copied, the method can access and mutate the object, but it cannot change which object the original variable points to.

The Role of Immutability and Final

If a class is immutable, like String or Integer, you cannot change its internal state. Passing an immutable object to a method and reassigning the parameter has no effect on the original variable. The final keyword on a parameter prevents reassignment inside the method, which can clarify that the method should not change the reference. For example:

public class FinalParameter { static void process(final StringBuilder sb) { sb.append(" world"); // sb = new StringBuilder(); // compile error } }

Using final on parameters is a style choice that makes the pass-by-value behavior explicit: the reference cannot be reassigned, but the object's mutable state can still be changed.

Practical Implications for API Design

Understanding pass by value is critical when designing method signatures. If you want a method to modify an object, the caller must pass a mutable object and the method must modify its fields or call its methods. If you want to return a new value, you should return it explicitly. For example, a method that increments an integer cannot change the caller's variable unless you return the new value:

public class Increment { static int increment(int value) { return value + 1; } public static void main(String[] args) { int count = 5; count = increment(count); System.out.println(count); // prints 6 } }

This pattern is common in functional-style code where methods avoid side effects.

Memory and Performance Considerations

Passing a reference is cheap because only the reference (typically a 64-bit pointer) is copied, not the entire object. This is a key reason Java does not copy objects when passing them to methods. Copying large objects would be expensive and would require deep-copy logic. The pass-by-value mechanism for references means that method calls have low overhead, but it also means that objects are shared between the caller and the method. This sharing has implications for concurrency: if multiple threads hold the same reference, they can mutate the object concurrently, leading to race conditions. You need to design mutable objects with thread safety in mind or use immutable objects to avoid shared-state issues.

java why java is pass by value: Practical Usage and Code Exa | RYUSLOG DEV