Fundamentals 19 min read

Why Java Uses Value Passing for All Parameters – A Deep Dive into JVM Memory and Reference Behavior

This article explains why Java treats all method arguments as value‑passed, explores the JVM memory model, distinguishes between primitive and reference types, and demonstrates through code examples how parameter passing affects variables and objects in practice.

Java Backend Technology
Java Backend Technology
Java Backend Technology
Why Java Uses Value Passing for All Parameters – A Deep Dive into JVM Memory and Reference Behavior

1. Formal Parameters and Actual Arguments

We first review the syntax of formal parameters (the variables defined in a method signature) and actual arguments (the values passed when the method is called).

Formal parameter: a variable that exists only during the method execution and occupies memory on the stack. Actual argument: the real value initialized before the method call and supplied to the formal parameter.
public static void func(int a){
    a = 20;
    System.out.println(a);
}

public static void main(String[] args){
    int a = 10; // variable
    func(a);
}

In this example, a in main is the actual argument, while a in func is the formal parameter.

2. Java Data Types

Data types define how values are stored in memory. Java has two categories:

Primitive types: byte, short, int, long, float, double, char, boolean. Reference types: classes, interfaces, arrays.

The JVM manages these types according to its memory layout.

3. JVM Memory Layout and Responsibilities

The JVM divides runtime memory into several areas:

Virtual Machine Stack

Heap

Program Counter

Method Area

Native Method Stack

Each area stores specific data during program execution.

Virtual Machine Stack : Stores stack frames for each method call, including local variables, operand stack, and return address.
Heap : Stores objects and arrays; shared among all threads.
Method Area : Holds class metadata, static variables, and runtime constant pool; shared and thread‑safe.
Native Method Stack : Similar to the VM stack but for native (non‑Java) method calls.
Program Counter : Thread‑local pointer to the current bytecode instruction.

4. How Data Is Stored in Memory

Primitive local variables reside on the stack, while primitive member variables and static variables are stored in the heap and method area respectively. Reference variables hold addresses pointing to objects on the heap.

5. Value Passing vs Reference Passing

Value passing : The method receives a copy of the actual argument. Modifying the formal parameter does not affect the original value.

public static void valueCrossTest(int age, float weight){
    System.out.println("Input age: " + age);
    System.out.println("Input weight: " + weight);
    age = 33;
    weight = 89.5f;
    System.out.println("After reassignment age: " + age);
    System.out.println("After reassignment weight: " + weight);
}

public static void main(String[] args){
    int a = 25;
    float w = 77.5f;
    valueCrossTest(a, w);
    System.out.println("After method call age: " + a);
    System.out.println("After method call weight: " + w);
}

Output shows that a and w remain unchanged after the method call.

Reference passing : The method receives a copy of the reference (address). Changing the object's fields via the formal parameter affects the original object, but reassigning the formal parameter to a new object does not affect the caller's reference.

public static void PersonCrossTest(Person person){
    System.out.println("Input name: " + person.getName());
    person.setName("I am Zhang Xiaolong");
    System.out.println("After reassignment name: " + person.getName());
}

public static void main(String[] args){
    Person p = new Person();
    p.setName("I am Ma Huateng");
    p.setAge(45);
    PersonCrossTest(p);
    System.out.println("After method call name: " + p.getName());
}

When the method reassigns person = new Person();, the caller's reference still points to the original object, demonstrating that Java always passes arguments by value (a copy of the reference for objects).

Conclusion

In Java, all parameters are passed by value: primitives pass their actual values, and object references pass a copy of the reference. Modifying an object's fields via the copied reference affects the original object, while reassigning the copied reference does not.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaParameter PassingValue vs ReferenceJVM Memory
Java Backend Technology
Written by

Java Backend Technology

Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.