Does Java pass by reference? [duplicate]
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?
Solution 1:
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.
Solution 2:
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.
Solution 3:
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.