4

Consider this piece of code:

String baz = "Hello";
String foo = "Hello";
return foo.equals(baz); // Returns true as expected
return(baz == foo); // Also returns true!

Why does the == operator also return true in this case? It should be comparing the locations of the objects themselves, not their values.

I'm assuming that Java does some sort of internal work and determines these two are of type String (or Integer, etc.) so it implicitly calls the .equals() method.

I'm curious to know exactly how this is done (ie. what goes on in the background), and why this is done, what if I actually wanted to test their location in memory?

user2864740
  • 60,010
  • 15
  • 145
  • 220
Tiberiu
  • 990
  • 2
  • 18
  • 36
  • 3
    This is very similar to a quite popular thread found here: http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java – Matt Jones Oct 05 '14 at 04:26
  • @MattJones: the same coin, but the flip side. – Michael Burr Oct 05 '14 at 04:37
  • 1
    @MattJones Thanks. I hadn't seen that thread. Although it contained my answer, I don't think this should be marked as duplicate, as someone looking for the same answer probably won't look in that thread because the question is inherently different – Tiberiu Oct 05 '14 at 04:42
  • @Tiberiu: Yes indeed that marked question wasn't really exact duplicate of your question and that's why I reopened your question. – anubhava Oct 05 '14 at 04:44
  • 5
    I think it **should** be marked as a duplicate. This question will still exist even though it is marked as a duplicate, and people can still find their way over (and back). There is absolutely nothing new added by any answers left here and the high-voted answers in the duplicate cover string interning in some fashion. – user2864740 Oct 05 '14 at 04:54
  • @user2864740 oh ok, I thought marking it as duplicate meant it would hide it. Still new to stackoverflow, thanks! – Tiberiu Oct 05 '14 at 15:45

1 Answers1

8

return(baz == foo) is also returning true because all literal strings are interned in Java. When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.

So in short due to use of String intern pool for your case return(baz == foo) is behaving same as return(baz.equals(foo))

Read more about String literals in Java Specs

Community
  • 1
  • 1
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 1
    Makes sense, thanks. I'm assuming the exact same thing is done in the case of the other java objects? (`Integer` etc.) – Tiberiu Oct 05 '14 at 04:46
  • 1
    For int also it keeps a constant pool up to value=127. [See this answer for more info on Integers constants](http://stackoverflow.com/questions/13098143/java-integer-constant-pool) – anubhava Oct 05 '14 at 04:49
  • 2
    String literals are special, as is the String intern pool. If you use `new` you will get a new object. Some classes do have static factory methods that can return an existing object with the right value. – Patricia Shanahan Oct 05 '14 at 05:24