- Java is Pass by Value, Not Pass by Reference
- Demonstrating pass by value
- The Example swap() Method Explained
- The Example changeValue() Method Explained
- Conclusion
- How is Java Pass by Value and Not by Reference [4 Examples]
- What is Pass by Value?
- What is Pass by Reference?
- Examples to prove Java Pass By Value
- Primitive
- Regular Objects
- Collections Objects
- Java Pass By Value Tutorial Source Code
Java is Pass by Value, Not Pass by Reference
Many Java programmers question whether Java is pass by value or pass by reference. This article summarizes why Java is always pass by value.
First, what does pass by value and pass by reference mean?
- Pass by value: The method parameter values are copied to another variable and then the copied object is passed to the method. The method uses the copy.
- Pass by reference: An alias or reference to the actual parameter is passed to the method. The method accesses the actual parameter.
Often, the confusion around these terms is a result of the concept of the object reference in Java. Technically, Java is always pass by value, because even though a variable might hold a reference to an object, that object reference is a value that represents the object’s location in memory. Object references are therefore passed by value.
Both reference data types and primitive data types are passed by value. Learn more about data types in Java.
In addition to understanding data types, it’s also important to understand memory allocation in Java, because reference data types and primitive data types are stored differently.
Demonstrating pass by value
The following example demonstrates how values are passed in Java.
The example program uses the following class:
public class Balloon private String color; public Balloon() > public Balloon(String c) this.color = c; > public String getColor() return color; > public void setColor(String color) this.color = color; > >
The following example program uses a generic method, swap() , that swaps two variables. Another method, changeValue() , attempts to change the variable values.
public class Test public static void main(String[] args) Balloon red = new Balloon("Red"); // memory reference = 50 Balloon blue = new Balloon("Blue"); // memory reference = 100 swap(red, blue); System.out.println("After the swap method executes:"); System.out.println("`red` color value = " + red.getColor()); System.out.println("`blue` color value = " + blue.getColor()); changeValue(blue); System.out.println("After the changeValue method executes:"); System.out.println("`blue` color value = " + blue.getColor()); > // Generic swap method public static void swap(Object o1, Object o2) Object temp = o1; o1 = o2; o2 = temp; > private static void changeValue(Balloon balloon) // balloon = 100 balloon.setColor("Red"); // balloon = 100 balloon = new Balloon("Green"); // balloon = 200 balloon.setColor("Blue"); // balloon = 200 > >
When you execute the example program, you get the following output:
OutputAfter the swap method executes: 'red' color value = Red 'blue' color value = Blue After the changeValue method executes: 'blue' color value = Red
The output shows that the swap() method didn’t swap the color values of the original objects. This helps to show that Java is pass by value, since the swap() method only acts upon copies of the original object reference values.
This swap() method test can be used with any programming language to check whether it’s pass by value or pass by reference.
The Example swap() Method Explained
When you use the new operator to create an instance of a class, the object is created and the variable contains the location in memory where the object is saved.
Balloon red = new Balloon("Red"); Balloon blue = new Balloon("Blue");
Here’s a step-by-step breakdown of what happens when the swap() method executes:
- Assume that red is pointing to memory location 50 and blue is pointing to memory location 100, and that these are the memory locations of both Balloon objects.
- When the class calls the swap() method with the red and blue variables as arguments, two new object variables, o1 and o2 , are created. o1 and o2 also point to memory locations 50 and 100 respectively.
- The following code snippet explains what happens within the swap() method:
public static void swap(Object o1, Object o2) // o1 = 50, o2 = 100 Object temp = o1; // assign the object reference value of o1 to temp: temp = 50, o1 = 50, o2 = 100 o1 = o2; // assign the object reference value of o2 to o1: temp = 50, o1 = 100, o2 = 100 o2 = temp; // assign the object reference value of temp to o2: temp = 50, o1 = 100, o2 = 50 > // method terminated
Since the variables contain the reference to the objects, it’s a common mistake to assume that you’re passing the reference and Java is pass by reference. However, you’re passing a value which is a copy of the reference and therefore it’s pass by value.
The Example changeValue() Method Explained
The next method in the example program changes the color value of the object referenced by the blue variable:
private static void changeValue(Balloon balloon) // balloon = 100 balloon.setColor("Red"); // balloon = 100 balloon = new Balloon("Green"); // balloon = 200 balloon.setColor("Blue"); // balloon = 200 >
Here’s a step-by-step breakdown of what happens within the changeValue() method:
- The class calls the changeValue() method on the blue variable that references memory location 100. The first line creates a reference that also points to memory location 100. The color value of the object at memory location 100 is changed to «Red» .
- The second line creates a new object (with color value «Green» ). The new object is at memory location 200. Any further methods executed on the balloon variable act upon the object at memory location 200, and don’t affect the object at memory location 100. The new balloon variable overwrites the reference created in line 1 and the balloon reference from line 1 is no longer accessible within this method.
- The third line changes the color value of the new Balloon object at memory location 200 to «Blue» , but does not affect the original object referenced by blue at memory location 100. This explains why the final line of the example program output prints blue color value = Red , which reflects the change from line 1.
Conclusion
In this article you learned about why Java is pass by value. Continue your learning with more Java tutorials.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
How is Java Pass by Value and Not by Reference [4 Examples]
There is a common confusion in Java Developers especially who have worked with C/C++, whether Java is “Pass by Value” or “Pass by Reference”.
What is Pass by Value?
In Pass by Value, the method parameter values are copied to another variable and then the copied object is passed. Any changes that happen inside the method happen on this copy of the variable, which means that the value of the original parameter passed in the method will be unchanged outside the method scope.
What is Pass by Reference?
In Pass by Reference, an alias or reference to the actual parameter is passed to the method. As the actual method is passed, any changes made in the method on the parameter will be observed outside the method scope also.
Java is Strictly “Pass by Value”
Examples to prove Java Pass By Value
Let’s observe some examples and try to clear this confusion once and for all.
For the sake of simplicity, we will divide the clarification into 3 parts:
Primitive
public static void main(String[] args) < int number = 1; System.out.println("Main Method before the change(): " + number); change(number); System.out.println("Main Method after the change(): " + number); >public static void change(int number)
Main Method before the change(): 1 Change Method: 10 Main Method after the change(): 1
It is very obvious that in the above code, Java has passed the 10 in variable number instead of passing the reference of variable number.
So any change in number inside method change, will not impact variable number outside the change method.
Regular Objects
package com.adevguide.java.generic; public class PassByValueReference < public static void main(String[] args) < Vehicle car = new Vehicle("4-Wheeler", "Mercedes G", "Black"); Vehicle bike = new Vehicle("2-Wheeler", "Yamaha FZS", "Yellow-Green"); System.out.println("Before the Swap: "); System.out.println("Car(v1) name: " + car.getName()); System.out.println("Bike(v2) Color: " + bike.color); swap(car, bike); System.out.println("After the Swap: "); System.out.println("Car(v1) name: " + car.getName()); System.out.println("Bike(v2) Color: " + bike.color); >public static void swap(Vehicle v1, Vehicle v2) < Vehicle temp = v1; // Creating Temp Vehicle object v1 = v2; // Swapping v1 and v2 v2 = temp; System.out.println("Inside swap: v1 color: " + v1.getName()); System.out.println("Inside swap: v2 color: " + v2.getName()); >> class Vehicle < private String type; private String name; String color; public String getType() < return type; >public void setType(String type) < this.type = type; >public String getName() < return name; >public void setName(String name) < this.name = name; >public Vehicle(String type, String name, String color) < this.type = type; this.name = name; this.color = color; >>
Before the Swap: Car(v1) name: Mercedes G Bike(v2) Color: Yellow-Green Inside swap: v1 color: Yamaha FZS Inside swap: v2 color: Mercedes G After the Swap: Car(v1) name: Mercedes G Bike(v2) Color: Yellow-Green
When I said that Java is strictly passed by value, I meant it. As we cannot directly pass the value of an object just like primitives in the method, Java passes the reference of the parameter as value.
Java manipulates objects ‘by reference,’ but it passes object references to methods ‘by value’.
For simplicity, you can think that Java always creates a new object for every parameter type and then assign the actual reference of the parameter to this.
So any changes (like swap) made to this method parameter will be valid only inside the scope of the method.
In our example, v1 has a reference same as the car and v2 has a reference same as the bike. Now once the swap is performed inside the method, v1 has the same reference as the bike and v2 has the same reference as the bike.
As the scope of v1 and v2 is only inside method swap(), the values of car and bike objects are still intact.
When instead of a swap if we try to alter the value of the object, the changes will be available outside the method also because the changes will be made to the reference of the object which is passed as value.
package com.adevguide.java.generic; public class PassByValueReference < public static void main(String[] args) < Vehicle car = new Vehicle("4-Wheeler", "Mercedes G", "Black"); Vehicle bike = new Vehicle("2-Wheeler", "Yamaha FZS", "Yellow-Green"); Vehicle oldCar = car; Vehicle oldBike = bike; System.out.println("Before the change: "); System.out.println("Car(v1) is: " + car.toString()); System.out.println("Bike(v2) Color: " + bike.toString()); change(car, bike); System.out.println("After the change: "); System.out.println("Car(v1) is: " + car.toString()); System.out.println("Bike(v2) is: " + bike.toString()); System.out.println(oldCar == car); // true System.out.println(oldBike == bike); // true >public static void change(Vehicle v1, Vehicle v2) < v1.setName("Honda Jazz"); // v1 is pointing towards car Vehicle temp = v1; // Creating Temp Vehicle object v2.setName("Pulsur"); //// v1 is pointing towards bike v1 = v2; // Swapping v1 and v2 v1.color = "Green"; // v1 is pointing towards bike v2 = temp; // v2 is pointing towards car v2.color = "red"; //// v1 is pointing towards car System.out.println("Inside swap: v1 is: " + v1.toString()); System.out.println("Inside swap: v2 is: " + v2.toString()); >> class Vehicle < private String type; private String name; String color; public String getType() < return type; >public void setType(String type) < this.type = type; >public String getName() < return name; >public void setName(String name) < this.name = name; >public Vehicle(String type, String name, String color) < this.type = type; this.name = name; this.color = color; >@Override public String toString() < return "Vehicle [type=" + type + ", name=" + name + ", color=" + color + "]"; >>
Before the change: Car(v1) is: Vehicle [type=4-Wheeler, name=Mercedes G, color=Black] Bike(v2) Color: Vehicle [type=2-Wheeler, name=Yamaha FZS, color=Yellow-Green] Inside swap: v1 is: Vehicle [type=2-Wheeler, name=Pulsur, color=Green] Inside swap: v2 is: Vehicle [type=4-Wheeler, name=Honda Jazz, color=red] After the change: Car(v1) is: Vehicle [type=4-Wheeler, name=Honda Jazz, color=red] Bike(v2) is: Vehicle [type=2-Wheeler, name=Pulsur, color=Green]
In the above example, the change function is just a little modification of swap function. As I said before, Object v1 and v2 have a reference to car and bike.
Swap changes the reference of v1 to the bike and v2 to the car inside the method scope but they always point to one of these two objects. So changes made to v1 and v2 will always alter the value of the object it has a reference at that time.
Even the values of the object have changed now, but as OldCar and car are still pointing towards the same object, oldCar==car will return true.
Collections Objects
Collections like List, Map, Set follows the same rules as a regular object.
package com.adevguide.java.generic; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class PassByValueReference < public static void main(String[] args) < Mapmap = new HashMap(); map.put("A", 1); map.put("B", 2); List list = new ArrayList(); list.add(10); list.add(20); System.out.println("map Before the Change(): " + map); System.out.println("list Before the Change(): " + list); change(map, list); System.out.println("map After the Change(): " + map); System.out.println("list After the Change(): " + list); > public static void change(Map m1, List l1) < m1.put("C", 3); l1.add(30); MapnewMap = new HashMap(); newMap.putAll(m1); newMap.put("D", 4); List newList = new ArrayList(); newList.addAll(l1); newList.add(40); Map lastMap = m1; List lastList = l1; lastMap.remove("A"); lastList.remove(0); System.out.println("Inside Change Method:"); System.out.println("m1 is: " + m1); System.out.println("newMap is : " + newMap); System.out.println("lastMap is : " + lastMap); System.out.println("l1 is : " + l1); System.out.println("newList is : " + newList); System.out.println("lastList is : " + lastList); > >
map Before the Change(): list Before the Change(): [10, 20] Inside Change Method: m1 is: newMap is : lastMap is : l1 is : [20, 30] newList is : [10, 20, 30, 40] lastList is : [20, 30] map After the Change(): list After the Change(): [20, 30]
As we can see, map,m1, and lastMap have a common reference to an object whereas newMap points towards a different object. This means any changes made to either of map,m1, and lastMap will reflect in others too. Whereas newMap is independent of these changes.
Similarly, list,l1, and lastList have a common reference to an object whereas newList points towards a different object. This means any changes made to either of map,m1, and lastMap will reflect in others too. Whereas newList is independent of these changes.
Java Pass By Value Tutorial Source Code
You can find the complete source code used in this tutorial on Github.