Core Java

Java Pass by Reference vs Pass by Value Example

In this post, we feature a comprehensive Java Pass by Reference vs Pass by Value Example.

1. Introduction

There are two ways to pass arguments (parameters) into methods (functions) in most programming languages:

  • Pass by Reference – A reference to the actual parameter is passed to the method. If the method modifies the parameter variable, the changes are visible to the caller.
  • Pass by Value – The method parameter values are copied to another variable and then the copied value is passed. If the method modifies the parameter variable, the changes are not visible to the caller.
pass by reference vs pass by value

Java only supports “Pass by Value”. When an object is passed as an argument to a method, the reference to that object is passed.

Java manipulates objects by reference, and all object variables are references. Java new keyword creates a space in memory to hold the object structure and assigns a reference variable to the memory address.

In this example, I will demonstrate how Java passes the argument by value and how the object reference is passed to a method.

2. Technologies Used

The example code in this article was built and run using:

  • Java 11
  • Eclipse Oxygen

3. DataObject

In this step, I will create a DataObject class which has three data members: a number with the int type, a charValue with the char type, and a name with the String type.

It has three setters which sets the values for the data member and then modifies the argument’s value. It overrides the toString method to print out the object’s contents.

DataObject.java

package org.jcg.zheng;

public class DataObject {

    private char charValue;
    private String name;
    private int number;

    public char getCharValue() {
        return charValue;
    }

    public String getName() {
        return name;
    }

    public int getNumber() {
        return number;
    }

    public void setCharValue(char charValue) {
        this.charValue = charValue;

        charValue = 'X';
        System.out.println("\tUpdate charValue inside setCharValue, charValue=" + charValue);
    }

    public void setName(String name) {
        this.name = name;

        name = "Dummy" + name;
        System.out.println("\tUpdate name inside setName, name=" + name);
    }

    public void setNumber(int number) {
        this.number = number;

        number = number - 99;
        System.out.println("\tUpdate argument number inside setNumber, number=" + number);
    }

    @Override
    public String toString() {
        return "DataObject [number=" + number + ", charValue=" + charValue + ", name=" + name + "]";
    }

}

4. PassByValueTest

In this step, I will create a PassByValueTest to demonstrate Java’s “Pass by Value” and “Object Reference”.

First, I will create three private methods:

  • changeObject (DataObject dObj) – Invokes the setter to update the object’s contents. Although A method cannot change the reference itself, but it can change the object pointed to by the reference.
  • displayObjectIdentity (DataObject dObj) – Prints out the object’s hashcode and its contents. Java hides the actual memory address, so I will use the System.identityHashCode to identify the objects.
  • reAssignObject (DataObject dObj) – Re-assign the object reference passed from an argument to a different value.

I will create three test methods:

  • pass_by_value_with_primitive_type – The primitive arguments changed by the setters are not visible to the caller.
  • pass_by_value_with_object – The object reference argument changed by the function reAssignObject is not visible to the caller.
  • pass_by_value_with_object_2 – The object’s reference is not changed but the object content is changed by the function changeObject.

PassByValueTest.java

package org.jcg.zheng;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.Objects;

import org.junit.Test;

public class PassByValueTest {

    private void changeObject(DataObject dObj) {
        dObj.setName("Mary");
        dObj.setNumber(dObj.getNumber() + 1);
    }

    private void displayObjectIdentity(DataObject dObj) {
        System.out.println("\tidentityHashCode=" + System.identityHashCode(dObj) + ". Content="
                + dObj.toString());
    }

    private void reAssignObject(DataObject dObj) {
        System.out.println("Start reAssignObject:");
        displayObjectIdentity(dObj);
        // create a new DataObject object and create a temp with the object's reference value
        DataObject temp = new DataObject();
        dObj = temp;
        System.out.println("Completed reAssignObject:");
        displayObjectIdentity(dObj);
        assertTrue(Objects.equals(dObj, temp));
    }

    @Test
    public void pass_by_value_with_object() {
        DataObject dObj = new DataObject();
        dObj.setNumber(2);
        dObj.setCharValue('B');
        dObj.setName("Zheng");
        System.out.println("Before reAssignObject:");
        displayObjectIdentity(dObj);
        reAssignObject(dObj);
        System.out.println("After reAssignObject:");
        displayObjectIdentity(dObj);

        assertEquals("Zheng", dObj.getName());
        assertEquals(2, dObj.getNumber());
        assertEquals('B', dObj.getCharValue());

    }

    @Test
    public void pass_by_value_with_object_2() {
        DataObject dObj = new DataObject();
        dObj.setNumber(2);
        dObj.setCharValue('B');
        dObj.setName("Zheng");

        System.out.println("Before changeObject:");
        displayObjectIdentity(dObj);
        changeObject(dObj);
        System.out.println("After changeObject:");
        displayObjectIdentity(dObj);

        assertEquals("Mary", dObj.getName());
        assertEquals(3, dObj.getNumber());
        assertEquals('B', dObj.getCharValue());
    }

    @Test
    public void pass_by_value_with_primitive_type() {
        String mary = "Mary";
        int oneNum = 1;
        char charA = 'A';

        DataObject dObj = new DataObject();

        dObj.setNumber(oneNum);
        dObj.setCharValue(charA);
        dObj.setName(mary);

        assertEquals("Mary", mary);
        assertEquals(1, oneNum);
        assertEquals('A', charA);
    }

}

Note: changeObject, since the object’s reference is passed to the method as an argument, we can invoke the object’s setName to update the object’s name property.

Junit Output

C:\MaryZheng\Workspaces\java-pass-by-value>mvn install test
[INFO] Scanning for projects...
[INFO]
[INFO] --------------------< java-demo-pbv:java-demo-pbv >---------------------
[INFO] Building java-demo-pbv 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ java-demo-pbv ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory C:\MaryZheng\Workspaces\java-pass-by-value\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ java-demo-pbv ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to C:\MaryZheng\Workspaces\java-pass-by-value\target\classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ java-demo-pbv ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory C:\MaryZheng\Workspaces\java-pass-by-value\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ java-demo-pbv ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ java-demo-pbv ---
[INFO] Surefire report directory: C:\MaryZheng\Workspaces\java-pass-by-value\target\surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running org.jcg.zheng.PassByValueTest
        Update argument number inside setNumber, number=-97
        Update charValue inside setCharValue, charValue=X
        Update name inside setName, name=DummyZheng
Before reAssignObject:
        identityHashCode=532854629. Content=DataObject [number=2, charValue=B, name=Zheng]
Start reAssignObject:
        identityHashCode=532854629. Content=DataObject [number=2, charValue=B, name=Zheng]
Completed reAssignObject:
        identityHashCode=388043093. Content=DataObject [number=0, charValue= , name=null]
After reAssignObject:
        identityHashCode=532854629. Content=DataObject [number=2, charValue=B, name=Zheng]
        Update argument number inside setNumber, number=-97
        Update charValue inside setCharValue, charValue=X
        Update name inside setName, name=DummyZheng
Before changeObject:
        identityHashCode=266437232. Content=DataObject [number=2, charValue=B, name=Zheng]
        Update name inside setName, name=DummyMary
        Update argument number inside setNumber, number=-96
After changeObject:
        identityHashCode=266437232. Content=DataObject [number=3, charValue=B, name=Mary]
        Update argument number inside setNumber, number=-98
        Update charValue inside setCharValue, charValue=X
        Update name inside setName, name=DummyMary
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.217 sec

Results :

Tests run: 3, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  9.494 s
[INFO] Finished at: 2019-03-23T17:52:46-05:00
[INFO] ------------------------------------------------------------------------

C:\MaryZheng\Workspaces\java-pass-by-value>

5. Java Pass by Reference vs Pass by Value Example – Summary

In this example, I created a DataObject class and three test cases to demonstrate how Java “pass by value” works. Java always passes by value for the parameters and always stores the object’s reference as a value.

Java and C languages support “Pass By Value” only. C++ supports both “Pass by Value” and “Pass by Reference”.

6. Download the Source Code

This example consists of a project with two classes: DataObject and PassByValueTest to demonstrate the Java’s “Pass by Value” and “Object Reference”.

Download
You can download the full source code of this example here: Java Pass by Reference vs Pass by Value Example

Last updated on Aug. 13, 2019

Mary Zheng

Mary has graduated from Mechanical Engineering department at ShangHai JiaoTong University. She also holds a Master degree in Computer Science from Webster University. During her studies she has been involved with a large number of projects ranging from programming and software engineering. She works as a senior Software Engineer in the telecommunications sector where she acts as a leader and works with others to design, implement, and monitor the software solution.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Wiliam Ferraciolli
4 years ago

Thank you

Back to top button