backToBasics: Same VM, everything in Java is pass by value
Let’s refresh the topic for all the variables running in a single virtual machine “Everything in Java is pass by value”,
Some newcomers may think, in java pass by value only for primitives, and pass by reference for objects,
Method declaration could take primitive, object reference arguments or both. When we pass the object variable into a method, then we pass the copy of the object reference of that variable to the method not the actual object.
We will understand this with following bitterSwap method.
Classic swap function explanation, the following method is suppose to swap the arguments values,
1. public void bitterSwap(T swap1, T swap2) {
2. T temp = swap1;
3. swap1 = swap2;
4. swap2 = temp;
5. }
For example MyClass myClass = new MyClass(), is having unique memory address in java VM heap.
Here T is an argument type and its java (not c++…etc), the above method will not swap the values, then what’s wrong?
back to basics 🙂 for all the variables running in a single virtual machine “Everything in Java is pass by value”,
The Java Language Specification (JLS) states,
http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.1
As said above we are passing the copy of the reference of the variable, so after passing the copy of reference to bitterSwap we are having two variable reference first original variable reference, second the copy of that variable reference, but both are pointing to same object.
In either cases passing primitive or reference variable, always we copy the reference of that object, any time we can’t change the reference of original variable, but could change/modify the object to which the original variable is refereeing. To simplify this let imagine variable a container of type T.
In bitterSwap method we are swapping the contents of arguments/pointers, but not the values or objects to which they are pointing, we call our cursed bitterSwap method,
27. PassByValue td = new PassByValue();
28. MyClass origVar1 = new MyClass("original myClass 1");
29. MyClass origVar2 = new MyClass("original myClass 2");
30. td.bitterSwap(origVar1, origVar2);
31.
32. System.out.println("origVar1 = " + origVar1);
33. System.out.println("origVar2 = " + origVar2);
T origVar1 states, origVar1 is a container of type T, having a object data as original myClass 1.
T origVar2 states, origVar2 is a container of type T, having a data object as original myClass 2.
Other side bitterSwap method signatures are bitterSwap(T swap1, T swap2), which also states as follows,
T swap1 states, swap1 is a container of type T.
T swap2 states, swap2 is a container of type T.
Inside the bitterSwap() method line #4 type T temp = swap1, temp is another container which holds the reference to the same object where swap1 is referring. Container swap1 will have swap2 values and container swap2 will have temp values.
Now on calling the line #30, we are just putting the value1 and value2 in the bitterSwap containers, can’t not replace the container swap1 with origVar1, swap2 with origVar2.
As stated above we can’t modify the original references of the object so origVar1 and origVar2 line #28 and line #29 (for others #12, #13, #20, #21)!! Will be having their original values.
[file lang=”java” link=”on”]downloads/PassByValue.java[/file]
and supporting class,
[file lang=”java” link=”on”]downloads/MyClass.java[/file]