0

So we know that Java uses pass by value, i.e. it passes a copy of the reference to the methods. I am wondering why is it then, that when I test the parameter reference (param in my example) with the original reference (string in my example) is says they are the same?

Shouldn't the following code return false, i.e. the references are not the same, because a copy reference (i.e. a new reference) is passed by value?

public class Interesting {

  private String string;

  public Interesting(final String interestig) {
    super();
    string = interestig; // original reference is tested against copy reference and it says they are the same
  }

  public boolean isItTheSame(final String param) {
    return param == string;
  }

  public static void main(final String args[]) {
    Interesting obj = new Interesting("String");
    System.out.println(obj.isItTheSame(obj.string)); //copy of reference is created here
  }
}
Atti
  • 31
  • 6
  • 1
    I don't see any part that creates a copy? Which part do you think creates a copy? – Andrew Li Jun 10 '17 at 20:57
  • The OCA guide does: "The called method then gets its own copy of the reference variable to do with it what it likes." Chapter Passing Variables into Methods - OCA Objective 6.8 – Atti Jun 10 '17 at 21:07
  • 2
    @AndrewLi You are wrong. Atti quotes it correctly. The reference is copied. You think that is says that the object is copied, but this is not what this quote says. It's like copying a primitive value. – Tom Jun 10 '17 at 21:12
  • 1
    I wonder if "[Is Java "pass-by-reference" or "pass-by-value"?](//stackoverflow.com/q/40480)" is still a suitable dupe, because it covers variables and references and their behaviour pretty well. – Tom Jun 10 '17 at 21:21

3 Answers3

2

A reference variable is a reference. It contains a specific bit pattern​ that identifies the location of an object. This is known in computer science as a pointer. Per the JLS, "reference values (often just references) are pointers to these objects". Pointer values, like primitives, are passed to methods just by their bit pattern. That same pattern means they point to the same object. That's what == checks, whether two pointers point to the same object. That's why you get that result.

Radiodef
  • 37,180
  • 14
  • 90
  • 125
Lew Bloch
  • 3,364
  • 1
  • 16
  • 10
1

No, because == compares the value of the reference as well; it yields true if both references refer to the same object.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • But they are not the same reference ... if we reassign the parameter reference the original object will not be affected. – Atti Jun 10 '17 at 21:11
  • @Atti This is correct, but you don't reassign anything here. – Tom Jun 10 '17 at 21:14
  • @Michael: but I thought that if we have two different references and == tests the references it would be false ... what am I missing here? Thanks! – Atti Jun 10 '17 at 21:16
  • 1
    @Atti: Two different references to the same object contain the same value, just like two different int variables can contain the same value, and in both cases the values are considered equal. And what would even be the point of comparing references for identity rather than equality? What would you need it for? That two references refer to the same object is a useful information in many circumstances. – Michael Borgwardt Jun 10 '17 at 22:18
0

A reference is a value of its own. The string "String" lives at a specific memory location, say 0x01ab64e. Therefore, the value of any reference referring to that string is 0x01ab64e. There can be no reference to that string with a different value, because then it will not be referring to that string, it will be referring to a different string.

"Pass by value" refers to passing the reference by value, not passing the actual referenced object (the string) by value. So, the exact same reference is passed. That's why it is the same.

To verify that the reference is passed by value, (and that the value is a copy,) try this:

String s = null;
foo( s );
assert s == null;

void foo( String s )
{
    s = "not null";
}

The assertion does not fail, which means that the reference s held by the caller was not altered. Which means that the reference s was passed by value, (which is always a copy,) so foo() only changed the value of its own copy of the reference, leaving the copy of the caller unaffected.

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
  • but is the parameter `s` (in the `foo` method) not a different reference then the `String s` in your first line? – Atti Jun 10 '17 at 21:15
  • @Atti You should really start to differ __variables__ and __references__. Two different variables (like `s` from the first line and `s` from the method parameter) still can have the same reference to the same String object in heap. They will then differ when you do `s = "not null"` in `foo`. – Tom Jun 10 '17 at 21:17
  • 1
    @Mike: I got it. Thank you for the explanation! – Atti Jun 10 '17 at 21:25