Равенство ссылок для java.яз..Строка в Scala


Можно было бы ожидать, что даже если строки неизменяемы, равенство значений и равенство ссылок не будут одинаковыми для java.яз..Строковые объекты в Scala. Это означает, что две строки, содержащие vals, не должны быть равными ссылкам, даже если их строки идентичны. Но вот что я получаю в 2.9.1.окончательный ОТВ:

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

scala> s1 eq s2
res0: Boolean = true

Есть идеи, почему результат не был false? Тот же эксперимент с List("a") вместо "a" работает, как и ожидалось. Метод eq помечается как окончательный в AnyRef . Существует ли какая-либо магия компилятора, сделанная специально для String или java.lang.String?

2 5

2 ответа:

Да, это магия компилятора. В частности, это называетсяинтернирование . Java делает это также, и это просто из соображений эффективности, таких как использование памяти и возможность сравнения без сравнения каждого символа. Вот статья в Википедии об этом . Вы также можете интернировать строки вручную с помощью метода intern().

Из спецификации языка Java :

Строковый литерал-это ссылка на экземпляр класса String (§4.3.1, §4.3.3).

Более того, строковый литерал всегда ссылается на один и тот же экземпляр класса String. Это происходит потому, что строковые литералы - или, более широко, строки, которые являются значениями постоянных выражений (§15.28) - "интернируются", чтобы совместно использовать уникальные экземпляры, используя метод String.intern.