Basics

8. Java Is Pass-by-Value

Java is strictly pass-by-value โ€” but for objects, the value passed is the reference (memory address). Reassigning a parameter never affects the caller; mutating the referenced object does.

Java 21 (core language)

Explanation

Java always passes copies of values to methods. For primitive types this is straightforward: the method gets a copy of the number, and changes inside the method don't affect the caller's variable.

For objects, the value passed is a copy of the reference (the memory address of the object). This means: if you reassign the parameter to a new object inside the method, the caller's reference is unchanged. But if you mutate the object's state through the reference (calling methods, changing fields), those mutations are visible to the caller โ€” because both the caller and the method reference the same heap object.

This is often misunderstood as "objects are passed by reference". They are not โ€” the reference itself is passed by value.

Example

import java.util.List;
import java.util.ArrayList;

public class PassByValue {
    static void tryReassign(String s) {
        s = "modified"; // only changes the local copy of the reference
    }

    static void mutateList(List<String> list) {
        list.add("added"); // mutates the object the reference points to
    }

    static void swapAttempt(int[] arr) {
        int tmp = arr[0]; arr[0] = arr[1]; arr[1] = tmp; // mutates the array object
    }

    public static void main(String[] args) {
        // Primitives: truly independent copy
        int x = 10;
        // (imagine a method that does x = 99 on its local param โ€” x is still 10 here)

        // Strings: reassigning inside method has no effect
        String str = "original";
        tryReassign(str);
        System.out.println(str); // "original" โ€” unchanged

        // Lists: mutation through the reference IS visible
        List<String> names = new ArrayList<>(List.of("Alice"));
        mutateList(names);
        System.out.println(names); // [Alice, added] โ€” mutation is visible

        // Arrays: same principle โ€” array is an object
        int[] pair = {1, 2};
        swapAttempt(pair);
        System.out.println(pair[0] + ", " + pair[1]); // 2, 1 โ€” mutation visible
    }
}

Sources