Reference equality for java.lang.String in Scala

3k Views Asked by At

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?

2

There are 2 best solutions below

0
On BEST ANSWER

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.

3
On

From the Java language specification:

A string literal is a reference to an instance of class String (§4.3.1, §4.3.3).

Moreover, a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern.