Select Page

Java is Pass-by-value

In Java all data is passed by value and not by reference. There are two categories:

  • Passing primitives to methods
  • Passing object references to methods

Why is it confusing?

This is a confusing topic in Java. The first question you might have after reading the sentence Passing object references to methods is that this sentence suggests that the object reference is passed. Because the word reference variable will let you focus on the word reference, When the reference variable is passed to the argument of a method, you will directly link the word reference to the passing mechanism. So the link to Pass-by-reference is easily made. Java is not Pass-by-reference and will be explained later.

How does it work

In Java the argument passed to a method is Pass-by-value.. But the meaning of value is different between primitive type and object. The value associated with an object is actually a pointer to the object in memory. This pointer is called a reference. The value of this pointer to the object is called object reference in Java specification.

To be precise, a copy of the object reference is passed. This is also the case with primitive. A copy is passed.

The meaning of valueWhat is passed to the argument of the method?
Primitive type
The actual data associated with the primitiveA literal copy of the primitive
ObjectA pointer to the object in memoryA copy of the reference variable, so a new reference variable has been created with the same memory address

Let’s clarify this with some code’s and figures:

public class Car {

   private String brand;
   private String registrationNumber;

   Car(String brand, String registrationNumber) {
       this.brand = brand;
       this.registrationNumber = registrationNumber;
   }

   public String getBrand() {
       return this.brand;
   }

   public void setBrand(String brand) {
       this.brand = brand;
   }

   public String getRegistrationNumber() {
       return this.registrationNumber;
   }

   public void setRegistrationNumber(String registrationNumber) {
       this.registrationNumber = registrationNumber;
   }

   @Override
   public String toString() {
       return "{" + " brand='" + getBrand()
       + "'" + ", registrationNumber='" + getRegistrationNumber() 
       + "'" + "}";
   }

}

 

public class SwapCarTest {
   /*
    * An example for showing that Java is Pass by value 
    * and not Pass by reference.
    */

   public static void main(String[] args) {
       Car car1 = new Car("Tesla", "123");
       Car car2 = new Car("VW", "456");

       System.out.println("------ Before swapCar -----");
       System.out.println("car1: " + car1);
       System.out.println("car2: " + car2);
       // try to swap the cars
       swapCar(car1, car2);

       System.out.println("------ After swapCar -----");
       System.out.println("car1: " + car1);
       System.out.println("car2: " + car2);

       // change a field of the object
       System.out.println("------ modify the brand to Temp -----");
       modifyBrand(car1);
       System.out.println("car1: " + car1);

   }

   public static void swapCar(Car c1, Car c2) {
       Car tempCar = new Car("Temp", "000");
       System.out.println("------ Start of swapCar -----");
       System.out.println("c1: " + c1);
       System.out.println("c2: " + c2);
       System.out.println("tempCar: " + tempCar);
       tempCar = c2;
       c2 = c1;
       c1 = tempCar;
       System.out.println("------ End of swapCar -----");
       System.out.println("c1: " + c1);
       System.out.println("c2: " + c2);
       System.out.println("tempCar: " + tempCar);

   }

   public static void modifyBrand(Car car) {
       System.out.println("Start modigfyBrand, car: " + car);
       car.setBrand("Temp");
       System.out.println("End modigfyBrand, car: " + car);
   }

}

In main program, before swapCar method is called. Two Car objects are created. Reference variable car1 contains the memory address of object Car with brand Tesla and registration number 123 as shown in Figure 1.

Car car1 = new Car("Tesla", "123");
Car car2 = new Car("VW", "456");

A copy of the reference variable car1 and a copy of the reference variable car2 are passed to the method swapCar. These are c1 and c2. In the method swapCar a new object tempCar is created as shown in Figure 2.

Car tempCar = new Car("Temp", "000");

The interesting part begins here. The swap happens only to the reference variables c1, c2 and tempCar. The original reference variables car1 and car2 still point to the same objects and are not modified by the method as shown in Figure 3.

tempCar = c2;
c2 = c1;
c1 = tempCar;

Note that the state of the original object can be modified by the reference variable car which is a copy of the reference variable car1. Reference variable car points to the original object. The object field brand can be modified as shown in Figure 4.

Output:

$ java SwapCarTest
------ Before swapCar -----
car1: { brand='Tesla', registrationNumber='123'}
car2: { brand='VW', registrationNumber='456'}
------ Start of swapCar -----
c1: { brand='Tesla', registrationNumber='123'}
c2: { brand='VW', registrationNumber='456'}
tempCar: { brand='Temp', registrationNumber='000'}
------ End of swapCar -----
c1: { brand='VW', registrationNumber='456'}
c2: { brand='Tesla', registrationNumber='123'}
tempCar: { brand='VW', registrationNumber='456'}
------ After swapCar -----
car1: { brand='Tesla', registrationNumber='123'}
car2: { brand='VW', registrationNumber='456'}
------ modify the brand to Temp -----
Start modigfyBrand, car: { brand='Tesla', registrationNumber='123'}
End modigfyBrand, car: { brand='Temp', registrationNumber='123'}
car1: { brand='Temp', registrationNumber='123'}

Summary

Java is Pass-by-value and not Pass-by-reference. If Java is Pass-by-Reference, then the actual reference variable is passed which is not the case. The main point to remember is that a copy of the reference variable is passed and not the actual reference variable. That is why Java is Pass-by-value and not Pass-by-reference.

Three cases to distinguish, one for primitive and two for object.

  • Passing primitives to methods

The primitive passed to the method remains the same after the execution of the method. Because a copy of the primitive is passed and this copy can be modified by the method.

  • Passing object references to methods when a method reassigns the received reference variable to another variable

The object reference passed to the argument of the method cannot be reassigned to another variable. Because only a copy of the reference variable is passed and not the original one. The method works only with the copy of the reference variable.

  • Passing object references to methods  when a method modifies the state of the object with the received reference variable

The state of the object can be modified with the object reference. For example by calling a setter method with the object reference.