Does Java really support passing by reference?
If it doesn't, why do we have the == operator for finding two objects with the same reference?
Does Java really support passing by reference?
If it doesn't, why do we have the == operator for finding two objects with the same reference?
Java uses pass by value, not by reference...
But, for non primitive types the value is the value of the reference.
So == compares the values of references for Objects.
Java does not use pass-by-reference but rather pass-by-value. Primitive value parameters are copied to the stack, as well as pointers to objects.
The ==
operator should be used for comparing primitive values, and for comparing object references.
For a detailed explanation, see my article "Java is Pass-By-Value, Dammit!"
Short answer is no. In Java there is only pass-by-value, and when you are working with objects (e.g. Object obj = new Object();
), you are working with object references. Which get passed by value.
For details, see: Parameter passing in Java
The point of distinction is between "pass**-by-reference" and "passing a** reference". You also sometimes see "call-by-..." and "pass-by-..." used interchangeably. For simplicity, I'll stick with "pass-by-...".
In academic, old-school, FORTRAN-relevant, comp-sci terminology, pass-by-reference means that the called code has access (reference) to a variable passed by the caller. Assigning to the formal parameter in the called code actually does an assignment to the caller's variable. The distinction is versus (among others) pass-by-value, which gives the called code a copy of the data (whatever it is) known to the caller.
In the contemporary Java-relevant, OO world, "having a reference" to an object means being able to get to the object itself. This is distinguished from "having a pointer" to emphasize (among other things) that one doesn't do "pointer arithmetic" on a reference. (In fact, a "reference" in this sense does not necessarily have to be an actual pointer-like memory address.)
Java passes arguments by value (in the first sense), but for object arguments, the value is a reference (in the second sense). Here's a bit of code that relies on the difference.
// called
public void munge(List<String> a0, List<String> a1) {
List<String> foo = new List<String>(); foo.add("everybody");
a0.set(0, "Goodbye");
a1 = foo;
}
// caller
...
List<String> l0 = new List<String>(); l0.add("Hello");
List<String> l1 = new List<String>(); l1.add("world");
munge(l0, l1);
...
Upon return from munge
, the caller's first list, l0
will contain "Goodbye"
. A reference to that list was passed to munge
, which called a mutating method on that referred-to object. (In other words, a0
received a copy of the value of l0
, which was a reference to a string list that got modified.)
However, upon return from munge
, the caller's second list, l1
still contains "world"
because no methods were called on the passed object reference (the value of l1
, passed by value to munge
). Instead, the argument variable a1
got set to a new value (the local object reference also held in foo
).
IF Java had used pass-by-reference, then upon return, l1
would have contained "everybody"
because a1
would have referred to the variable l1
and not simply been initialized to a copy of its value. So the assignment to a1
would have also been an assignment to l1
.
This same issue was discussed in another question, with ASCII-art to illustrate the situation.
Ya JAVA Does Not Support the Call By Reference..................