Java Pass-by-Value vs Pass-by-Reference

There are a lot of doubts about whether Java is pass-by-value or pass-by-reference.
This is often the case, especially with junior developers who are just learning the core functionality of the Java programming language.

Java is always pass-by-value.


The Java Spec says that everything in Java is pass-by-value. There is no such thing as “pass-by-reference” in Java. Even references to objects are passed-by-value.

Pass-By-Value in Java

The Pass-By-Value means that we are making a copy in memory of the actual parameter’s value that is passed in.

Let’s look at an example:

class Car {
    
  int numberOfSeats = 4;
    
  void addOneSeat(int numberOfSeats) {
    numberOfSeats = numberOfSeats + 1; // changes will only affect the local variable
  }
    
  public static void main(String args[]) {
    Car car = new Car();
    
    System.out.println("Number of seats before the change: " + car.numberOfSeats);
    
    car.addOneSeat(car.numberOfSeats);
    
    System.out.println("Number of seats after the change " + car.numberOfSeats);
  }
}
Output: Number of seats before the change: 4 Number of seats after the change 4

As you can see, the value of the numberOfSeats variable has not changed. Do you know why?

Because we only passed a copy of the value.

After that, all changes will be applied to that copy, while the variable’s original value will remain unchanged.
So in the method addOneSeat(), we changed the local variable’s value, not the instance variable.

Let’s look at another example:

 1  class Car {
 2    
 3   public String brand;
 4    
 5   public Car(String brand) {
 6     this.brand = brand;
 7   }
 8    
 9   public void setBrand(String brand) {
10     this.brand = brand;
11   }
12    
13   public static void main(String[] args) {
14     Car car = new Car("Ford");
15  
16     System.out.println(car.brand);
17  
18     changeReference(car);
19  
20     System.out.println(car.brand);
21  
22     modifyReference(car);
23  
24     System.out.println(car.brand);
25   }
26    
27   public static void changeReference(Car localCar) {
28     Car honda = new Car("Honda");
29     localCar = honda;
30   }
31    
32   public static void modifyReference(Car localCar) {
33     localCar.setBrand("Opel");
34   }
35  }
Output: Ford Ford Opel

What happens here?

Within the main method, on line 14, a new Car object is created, stored in memory, and the variable car is given the reference to the Car object. That is its address. Let’s say 1bad020a.

So the reference variable only holds the address of the object, not the object itself.
A variable car is located in the Stack and points to an object located in the Heap.

java object heap memory

On line 16, we print the value of the variable brand by calling it via a Car class reference.
And we get “Ford” as output.

On line 18, we call the changeReference method.
At that point, the localCar variable is created and the variable/reference car is copied bit-by-bit and passed to localCar inside the method.
Both car and localCar hold the same value of 1bad020a (both point to the same object).

Within the method, on line number 28, we created a new object and assigned its address to a variable honda.
On line 29, we pointed the localCar variable to the new object.
At this point, both localCar and honda are pointing to the same object.

And inside the main method, on line 20, we print the value of the brand variable, and the output is still “Ford” because the variable car still points to the original object.
In the changeReference method, we only set the local variable to point to the new object.

On line 22, we call the modifyReference method and at that point, the localCar variable is created and the variable/reference car is again copied bit-by-bit and passed to localCar inside the method.
Both car and localCar hold the same value of 1bad020a (both point to the same object).
Just like in the previous method.

Here’s the picture:

java object reference

And on the line below, we used the localCar variable to change the value of the brand variable within the Car object.
Both localCar and car point to the same Car object with “Opel” as brand value.

java references to objects in heap memory

When inside the main method, on line 24, we print the value of the brand variable using the car variable, we get a new “Opel” value, as expected.

That’s it!

 

Leave a Reply

Your email address will not be published.