stringscalareferenceequalityreferenceequals

Reference equality for java.lang.String in Scala


One would expect that even though strings are immutable, value-equality and reference-equality would not be the same for java.lang.String objects in Scala. This means that two string-holding vals should not be reference-equal even when their strings are identical. But here's what I get in a 2.9.1.final REPL:

scala> val s1 = "a"; val s2 = "a"
s1: java.lang.String = a
s2: java.lang.String = a

scala> s1 eq s2
res0: Boolean = true

Any idea why the result was not false? The same experiment with List("a") instead of "a" works as expected. The eq method is marked as final in AnyRef. Is there any compiler magic done specifically for String or java.lang.String?


Solution

  • Yes it's compiler magic. Specifically, it's called interning. Java does it as well, and it's simply for efficiency reasons, such as memory usage and allowing comparisons without comparing every character. Here's a Wikipedia article on it. You can also intern Strings manually with the intern() method.