Java: It is most certainly pass by value
November 5, 2010 13 Comments
I am surprised after all these years that this debate still happens between even seasoned Java developers. It isn’t really their fault though. Java made it a little confusing. If you want something more detailed, then you should read the following link.
I’m going to give you a quick overview that is not as detailed. Let’s start with a rule.
Java is pass by value regardless whether you are dealing with an object or a primitive
Everyone who writes java understands that when a method is called and a primitive is passed in, you get a copy of that variable and not the original. It is when passing an object that people get confused. The short of it is that the variable passed in is a cheap referenced copy of the original, but not really a pointer like in other languages like C++.
When you pass in an object, you can manipulate the values of elements of the object, but you cannot reassign the object to a new instance of that object because once you do, the link back to the object is completely broken. So if you call modifyIt(myClass) and in the method, you say myClass.someValue = ‘test’ and directly after the method call, the value of the original will be reflected by your change, but if you attempt to do this and reassign myClass to another object, your reference is lost.
Here is a class that illustrates the examples with some comments to help you along.
public class TestString {
private static void modifyIt(String modified) {
modified = "New String"; //This doesn't have any effect on the original
}
private static void modifyIt(int modified) {
modified = 2; //This doesn't have any effect on the original
}
private static void modifyIt(MyClass clazz) {
clazz.myValue = "new Value"; //This will work
clazz.intValue = 2; //this will work
clazz = new MyClass(); //Things will go south here.
clazz.myValue = "This value"; //you are throwing a toothpick in a volcano
clazz.intValue = 56; //Urinating in the wind
}
public static void main(String[] args) {
String value = "Original Value";
modifyIt(value);
// Prints only original value
System.out.println(value);
MyClass clazz = new MyClass();
modifyIt(clazz); //This method call has problems
System.out.println(clazz.myValue);
System.out.println(clazz.intValue);
int intValue = 1;
modifyIt(intValue);
// Only prints original value
System.out.println(intValue);
}
}
class MyClass {
public String myValue = "Original Value";
public int intValue = 1;
}
My personal preference is to always avoid even the remote possibility that these circumstances can even happen. You can do this by always returning the element in question from the method you are calling.
private static MyClass modifyIt2(MyClass clazz) {
clazz = new MyClass(); //Things will go south here. If Java was
//pass by reference, this would work
//but it is pass by value
clazz.myValue = "This value"; //you are throwing a toothpick in a volcano
clazz.intValue = 56; //Urinating in the wind
return clazz;
}
...
myClazz = modifyIt2(myClazz);
If you make an assignment back to your variables from the return of a method in all cases, this eliminates any question as to what object you have. This is also more object oriented and leans away from the function paradigm to a method paradigm.
The biggest thing I want everyone to take away from reading this is that Java is pass by value and not pass by reference, it is not even a mix.

Call it what ever you want, but java pass by a copy of reference.
Awkwardly put but true for objects
Pass by reference? Pass by value? I always say that the 'reference' is 'passed by value', because basically, that's what happens.
-Cameron McKenzie
TheServerSide.com
http://stackoverflow.com/questions/40480/is-java-pass-by-reference
Java does mostly pass by value. If you change an objects properties in a method then the referenced object is altered. Basically it depends on how you want to alter the object.
Correct, you're saying the same thing as the last comment, only a
lot more eloquent.
Java is pass by value only, absolute, without any constraints for references, as written explicitely in the JLS.
It is not confusing if you know what pass by value and pass by reference mean.
Jens, what's JLS ? where is the definition of this terms ?
Referring to the Java Language Specification. Semantically whatever helps you understand it the best works. I think of it as Pass by Value exclusively as well. The terminology is harder to grasp for those who didn't come from a C++ or C background since they have nothing to compare it to. Just understanding it enough to recognize it in a testing scenario is generally enough. Use your grey matter runtime…
It is “call by sharing”.
http://blog.lckymn.com/2010/11/12/java-uses-call-by-sharing/
It is “call by sharing”.
http://blog.lckymn.com/2010/11/12/java-uses-call-by-sharing/
http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.1
“When the method or constructor is invoked (ยง15.12), the values of the actual argument expressions initialize newly created parameter variables, each of the declared Type, before execution of the body of the method or constructor.”
> myClazz = modifyIt2(myClazz);
*How* is this more object-oriented? That's functional. OO is:
> myClazz.updateMyself();
OO relies on side-effects, inherently: instances contain their properties.
In your example you are going to pollute your object model with utility or functional operations on objects that don't make sense. Dog.runs() makes sense, but Dog.setAllMyValues() doesn't make real sense from an English language perspective. Your object model should be kept as pure as possible. What are you going to do if another circumstance requires different modification? Would you do this?
myClazz.updateMyself2()??
I don't think so.