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-...".

  1. 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.

  2. 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.