// Tutorial //

Java is Pass by Value and Not Pass by Reference

Published on August 3, 2022
Default avatar
By Pankaj
Developer and author at DigitalOcean.
Java is Pass by Value and Not Pass by Reference

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

One of the biggest confusion in Java programming language is whether java is Pass by Value or Pass by Reference. I ask this question a lot in interviews and still see the interviewee confused with it. So I thought to write a post about it to clear all the confusion around it. First of all, we should understand what is meant by pass by value or pass by reference.

  • Pass by Value: The method parameter values are copied to another variable and then the copied object is passed, that’s why it’s called pass by value.
  • Pass by Reference: An alias or reference to the actual parameter is passed to the method, that’s why it’s called pass by reference.

Update: I am getting a lot of comments and it seems that still there is a lot of confusion, so I have made a video tutorial to explain this in detail. Java is always Pass by Value and not pass by reference, we can prove it with a simple example. Let’s say we have a class Balloon like below.

package com.journaldev.test;

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;
	}
}

And we have a simple program with a generic method to swap two objects, the class looks like below.

package com.journaldev.test;

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("red color="+red.getColor());
		System.out.println("blue color="+blue.getColor());
		
		foo(blue);
		System.out.println("blue color="+blue.getColor());
		
	}

	private static void foo(Balloon balloon) { //baloon=100
		balloon.setColor("Red"); //baloon=100
		balloon = new Balloon("Green"); //baloon=200
		balloon.setColor("Blue"); //baloon = 200
	}

	//Generic swap method
	public static void swap(Object o1, Object o2){
		Object temp = o1;
		o1=o2;
		o2=temp;
	}
}

When we execute above program, we get following output.

red color=Red
blue color=Blue
blue color=Red

If you look at the first two lines of the output, it’s clear that swap method didn’t worked. This is because Java is pass by value, this swap() method test can be used with any programming language to check whether it’s pass by value or pass by reference. Let’s analyze the program execution step by step.

Balloon red = new Balloon("Red");
Balloon blue = new Balloon("Blue");

When we use new operator to create an instance of a class, the instance is created and the variable contains the reference location of the memory where the object is saved. For our example, let’s assume that “red” is pointing to 50 and “blue” is pointing to 100 and these are the memory location of both Balloon objects. Now when we are calling swap() method, two new variables o1 and o2 are created pointing to 50 and 100 respectively. So below code snippet explains what happened in the swap() method execution.

public static void swap(Object o1, Object o2){ //o1=50, o2=100
	Object temp = o1; //temp=50, o1=50, o2=100
	o1=o2; //temp=50, o1=100, o2=100
	o2=temp; //temp=50, o1=100, o2=50
} //method terminated

Notice that we are changing values of o1 and o2 but they are copies of “red” and “blue” reference locations, so actually there is no change in the values of “red” and “blue” and hence the output. If you have understood this far, you can easily understand the cause of confusion. Since the variables are just the reference to the objects, we get confused that we are passing the reference so java is passed by reference. However, we are passing a copy of the reference and hence it’s pass by value. I hope it clears all the doubts now. Now let’s analyze foo() method execution.

private static void foo(Balloon balloon) { //baloon=100
	balloon.setColor("Red"); //baloon=100
	balloon = new Balloon("Green"); //baloon=200
	balloon.setColor("Blue"); //baloon = 200
}

The first line is the important one, when we call a method the method is called on the Object at the reference location. At this point, balloon is pointing to 100 and hence it’s color is changed to Red. In the next line, ballon reference is changed to 200 and any further methods executed are happening on the object at memory location 200 and not having any effect on the object at memory location 100. This explains the third line of our program output printing blue color=Red. I hope the above explanation clears all the doubts, just remember that variables are references or pointers and its copies are passed to the methods, so java is always pass-by-value. It would be more clear when you will learn about Heap and Stack memory and where different objects and references are stored, for a detailed explanation with reference to a program, read Java Heap vs Stack.


Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.

Sign up
About the authors
Default avatar
Pankaj

author

Developer and author at DigitalOcean.

Still looking for an answer?

Was this helpful?

“Java is always Pass by Value and not pass by reference, we can prove it with a simple example” - totally WRONG! If java is “always Pass by Value” then when you pass an object to a method, you should have an ENTIRE COPY OF THAT OBJECT - as it happens in C++, and the method should operate solely on that COPY, not on the original! Objects in java are ALWAYS PASSED BY REFERENCE(which technique always uses a copy of the address where the original variable points to - people are confounding this with pass-by-value) the “swap” example is totally irrelevant as it doesn’t deal with “pass by reference” in any way, but it relies on the ability of a variable to point to another variable name, which is not permitted in java

- ccdan

    i think this is inaccurate statement, the ‘pass by value’ in java not always fall into your definition, for example, array, when you pass the array into a function it the copy of the reference to the underlying array that is passed into the function. so if you change the array the change is going to be reflected outside of the function call as well.

    - Zhe

      I think you are wrong, Method parameters stores reference addresses. How can you call it pass by value while it is storing references.

      - Zeynel

        public static void swap(Object o1, Object o2){ Object temp = o1; o1=o2; o2=temp; } o1 and o2 are local variables inside of the swap method’s scope. You just swapped the value of two local variables, why would it cause effect on the objects itself? You didn’t do anything with the 2 object.

        - bb

          You have clearly given the addresses copied in the function parameters too which is same as the called time address value. Hence, its passed by reference only. If it is passed by value, the value alone will be copied and the address will not be the same. Hence, the foo(Balloon balloon) function first line will not work if it copied by value alone. Since, it’s pass by reference, the modification happened on the location from ‘Blue’ to ‘Red’ reflected in the main() function where it is called. { Balloon red = new Balloon(“Red”); //memory reference 50 Balloon blue = new Balloon(“Blue”); //memory reference 100 foo(blue); System.out.println(“blue color=”+blue.getColor()); } private static void foo(Balloon balloon) { //baloon=100 balloon.setColor(“Red”); //baloon=100 balloon = new Balloon(“Green”); //baloon=200 balloon.setColor(“Blue”); //baloon = 200 } The problem here is, since the Java is not clear in call by reference (not exactly the pointer, the real method of handling the objects through addresses like in C & CPP) and pass by value, the new address assigned is not getting reflect in the called time variable’s / object’s address. Where it failed to copy/update the new address assigned in the called function to the original address. Somehow it seems like bug but, its the design actually and if you need to get the new addressed value, you have to get it on return value and assign in the calling area.

          - B Senthil Kumaran

            thanks for sharing, explanation is very clear.

            - kamlesh parmar

              if you have an array it is Pass by Reference … “Java is always Pass by Value” … seems to be wrong

              - Senecaek2

                This is awesome blog and i have increased my knowledge regarding java from this, thank you very much for writing this. Keep writing.

                - Ronak Vora

                  this article causes more confusion than explain anything clearly at all… :))) you say objects are copied before passed down? thats wrong… object are not, but their references are copied, objects stays the same that means, one can not dereference variable inside method because its a copy, BUT, and thats a big BUT that same copy points to same object as original reference so if you modified object it will be modified everywhere its used.

                  - levan

                    I think the confusion is about relativity. If you look at the object, then we can say it is passed by reference. If you look at the variable, then we can say it is passed by value (whatever it is, being an int, float or a reference towards an object). Method arguments are local variables anyways, of course they are passed by value. It is important to define the “what” that is passed to a method first. Seems evident to someone who got the subtility, not to target audience. It is not about Java vs C/C++, it is the same passing behaviour. The only difference is that in C/C++, you can have object variables and not only references towards objects, meaning that you pass an object by value. But a pointer or reference stays a variable which is passed by value, even if you use a pointer to a pointer to … to an object.

                    - someone