Java is Pass by Value and Not Pass by Reference
There has been a good amount of debate on whether "Java is pass by value or pass by reference?". Well, lets conclude it last time, Java is pass by value and not pass by reference. If it had been pass by reference, we should have been able to C like swaping of objects, but we can't do that in java. We know it already, right? When you pass a instance to a method, its memory address are copied bit by bit to new reference variable, thus both pointing to same instance. But if you change the reference inside method, original reference will not get chnage. If it was pass by reference, then it would have got changed also.
To prove it, lets see how memory allocations happen in runtime. It should solve the slightest doubts, if any. I am using following program for demonstration of the concept.
public class Foo { private String attribute; public Foo (String a){ this.attribute = a; } public String getAttribute() { return attribute; } public void setAttribute(String attribute) { this.attribute = attribute; } } public class Main { public static void main(String[] args){ Foo f = new Foo("f"); changeReference(f); // It won't change the reference! modifyReference(f); // It will change the object that the reference variable "f" refers to! } public static void changeReference(Foo a) { Foo b = new Foo("b"); a = b; } public static void modifyReference(Foo c) { c.setAttribute("c"); } }
Lets see what happen on runtime step by step :
1) Foo f = new Foo("f");
This statement will create a instance of class Foo, with 'attribute' initialized to 'f'. The reference to this created instance is assigned to variable f;
2) public static void changeReference(Foo a)
When this executes then a reference of type Foo with a name a is declared and it's initially assigned to null.
3) changeReference(f);
As you call the method changeReference, the reference a will be assigned to the object which is passed as an argument.
4) Foo b = new Foo("b"); inside first method
This will do exactly the same as in fisrt step, and will create a new instance of Foo, and assign it to b;
5) a = b;
This is the important point. Here, we have three reference variables and when statement executes, a and b will point to same instance created inside the method. Note: f is unchanged and it continuely pointing to instance, it was pointing originally. NO CHANGE !!
6) modifyReference(Foo c);
Now when this statement executed a reference, c is created and assigned to the object with attribute "f".
7) c.setAttribute("c");
This will change the attribute of the object that reference c points to it, and it's same object that reference f points to it.
I hope that this explanation was enough clear to make your understanding better, if it was not already.
Happy Learning !!
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)
Comments
Siryc Pups replied on Thu, 2013/03/07 - 5:12am
Java is pass(call) by sharing
Call by sharing
Lokesh Gupta replied on Thu, 2013/03/07 - 5:59am
in response to:
Siryc Pups
It also says that.. "The description "call-by-value where the value is a reference" is common (but should not be understood as being call-by-reference);"
So, it is ultimately call by value... right??
Robert Saulnier replied on Thu, 2013/03/07 - 8:38am
In step 2, the param a is a local variable. Local variables are not assigned default values. Param a is undefined till a value is assigned to it.
Tom Hartwell replied on Thu, 2013/03/07 - 2:04pm
in response to:
Robert Saulnier
While param a is local, it is not undefined and it does have a value. Its value is a reference to the Foo object created in the main method. Confusion is caused because the 'value' in the pass by value is a reference to the Foo object, but not the same reference as the one created in the main method.
Robert Saulnier replied on Thu, 2013/03/07 - 3:30pm
I didn't say it doesn't get a value, it gets assigned a value in step 3. I said in step 2, it is not assigned null. Step 2 should read:
When a method is called, a new Frame is created with an array of local variables. There is no mention of default values for those variables:
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.6.1
Lokesh Gupta replied on Thu, 2013/03/07 - 6:58pm
in response to:
Robert Saulnier
Tom Hartwell replied on Fri, 2013/03/08 - 3:55pm
in response to:
Tom Hartwell
@Robert, thanks for the clarification and the link.
Anilchandra Noo... replied on Fri, 2013/03/08 - 6:50pm
The Spec Says it is PassByValue. No debate.
Good explanation.