Conclusion
Myth: "Objects are passed by reference, primitives are passed by value"
Some proponents of this then say, "Ah, except for immutable objects which are passed by value [etc]" which introduces loads of rules without really tackling how Java works. Fortunately the truth is much simpler:
Truth #1: Everything in Java is passed by value. Objects, however, are never passed at all.
That needs some explanation - after all, if we can't pass objects, how can we do any work? The answer is that we pass references to objects. That sounds like it's getting dangerously close to the myth, until you look at truth #2:
Truth #2: The values of variables are always primitives or references, never objects.
This is probably the single most important point in learning Java properly. It's amazing how far you can actually get without knowing it, in fact - but vast numbers of things suddenly make sense when you grasp it.
Object x = null;
giveMeAString (x);
System.out.println (x);
[...]
void giveMeAString (Object y)
{
y = "This is a string";
}
the result (if Java used pass-by-reference semantics) would be
This is a string
instead of the actual result:
null
Explaining the two truths above eliminates all of this confusion.
So what does passing a reference by value actually mean?
It means you can think of references how you think of primitives, to a large extent. For instance, the equivalent to the above bit of code using primitives would be:
int x = 0;
giveMeATen (x);
System.out.println (x);
[...]
void giveMeATen (int y)
{
y = 10;
}
Now, the above doesn't print out "10". Why not? Because the value "0" was passed into the method giveMeTen
, not the variable itself. Exactly the same is true of reference variables - the value of the reference is passed in, not the variable itself. It's the same kind of copying that happens on variable assignment. The first code snippet, if inlined, is equivalent to:
// Before the method call
Object x = null;
// Start of method call - parameter copying
Object y = x;
// Body of method call
y = "This is a piece of string.";
// End of method call
System.out.println (x);
If you want to think pictorially, you might find my "objects are balloons, references are pieces of string" analogy helpful.
Comments