You are currently viewing How Java Passes Parameters: Primitives vs References

How Java Passes Parameters: Primitives vs References

Introduction

A common source of confusion for developers is how Java passes parameters to methods. Whether you are dealing with simple numbers or complex objects, understanding Java’s parameter-passing model is essential for writing bug-free, maintainable code. This article clarifies how Java passes both primitives and reference types to methods, debunks widespread misconceptions, and demonstrates key concepts with practical examples.

1. Java’s Parameter Passing Model

Java always uses pass-by-value when passing parameters to methods. This means that a copy of the value is made and used inside the method. However, because Java works with both primitive types and references to objects, the impact of pass-by-value can sometimes appear subtle or misleading.

“All arguments in Java are passed by value—what matters is whether the value is a primitive or a reference.”

For a solid foundation on Java variables, see our article on Declaring Java Variables.

2. Passing Primitive Data Types

When a primitive (such as int, double, or boolean) is passed to a method, the method receives a copy of the original value. Any changes made to the parameter inside the method do not affect the original variable.

“Primitives are like handing out photocopies—the original stays untouched.”

Example: Passing a Primitive

Before diving into code, consider this: when you pass an int to a method, only the value is copied.

// Demonstrates pass-by-value for primitives in Java
public void modifyPrimitive(int number) {
    number = number + 10; // This change affects only the local copy
    System.out.println("Inside method: " + number);
}

Description:
If you call modifyPrimitive(x) with x = 5, the original variable x remains 5 after the method, even though number inside the method is changed.

3. Passing Reference Types (Objects and Arrays)

When an object or array is passed to a method, the reference (i.e., the memory address) to the object is passed by value. Thus, both the caller and the callee have references pointing to the same object in memory. However, since the reference itself is copied, reassigning the parameter inside the method will not affect the original reference outside the method.

“With objects, Java hands you a copy of the address, not the house. You can rearrange the furniture, but you can’t move the house from the outside.”

Example: Modifying the State of an Object

Consider the following code, where an object’s internal state is modified:

// Demonstrates pass-by-value for references: modifying the object's state
public void modifyObject(Person person) {
    person.setName("Changed Name"); // This affects the original object
}

Description:
If you call modifyObject(p) and p is a Person object, the name inside the original Person is changed.

Example: Reassigning the Reference

What happens if you reassign the parameter?

// Demonstrates pass-by-value for references: reassigning the parameter
public void reassignReference(Person person) {
    person = new Person("New Name"); // This does NOT affect the original object
}

Description:
Although person now points to a new Person object inside the method, the original reference outside the method is unchanged.

For deeper insight into how Java manages memory for primitives and references, see Understanding the Stack and Heap in Java.

4. Special Case: Arrays as Reference Types

Arrays in Java are objects, and thus follow the same parameter-passing rules as other reference types. Modifying the contents of an array inside a method will reflect in the caller, but reassigning the parameter itself does not.

Example: Modifying an Array Element

// Modifies an element of an array
public void changeArray(int[] arr) {
    arr[0] = 99; // This change is visible outside the method
}

Description:
If you call changeArray(numbers) where numbers[0] was 5, it becomes 99 after the method.

5. Code Demonstration: Putting It All Together

The class below demonstrates the principles of Java parameter passing. Each method is fully commented to explain what is happening.

package com.kloudly;

// Demonstrates Java parameter passing for primitives and references
public class PassingParametersDemo {

    public static void main(String[] args) {
        PassingParametersDemo demo = new PassingParametersDemo();

        int primitive = 5;
        demo.modifyPrimitive(primitive);
        System.out.println("After method call, primitive: " + primitive);

        Person person = new Person("Original");
        demo.modifyObject(person);
        System.out.println("After method call, person's name: " + person.getName());

        demo.reassignReference(person);
        System.out.println("After reassignment, person's name: " + person.getName());

        int[] numbers = {1, 2, 3};
        demo.changeArray(numbers);
        System.out.println("After array modification, numbers[0]: " + numbers[0]);
    }

    // Changes local copy of primitive; original is unaffected
    public void modifyPrimitive(int number) {
        number += 10;
        System.out.println("Inside modifyPrimitive: " + number);
    }

    // Modifies object state via reference; original is affected
    public void modifyObject(Person person) {
        person.setName("Changed Name");
    }

    // Reassigns parameter to new object; original is unaffected
    public void reassignReference(Person person) {
        person = new Person("New Name");
    }

    // Modifies contents of the passed array
    public void changeArray(int[] arr) {
        arr[0] = 99;
    }

    // Simple Person class for demonstration
    static 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; }
    }
}

Description:
This code shows that primitives are never changed outside the method, while the state of referenced objects and arrays can be modified, but not their references.

Conclusion

In summary, Java always passes parameters by value—either the value of a primitive or the value of a reference. This distinction is vital for avoiding common bugs and writing predictable, robust Java code. Remember, Java never passes objects themselves, only references to them, and always by value.

For further exploration, read our articles on Declaring Java Variables and Understanding the Stack and Heap in Java.

“Understanding parameter passing is the key to mastering Java’s method behavior.”

You can find the complete code of this article on GitHub.

Noel Kamphoa

Experienced software engineer with expertise in Telecom, Payroll, and Banking. Now Senior Software Engineer at Societe Generale Paris.