Равенство ссылок для java.яз..Строка в Scala
Можно было бы ожидать, что даже если строки неизменяемы, равенство значений и равенство ссылок не будут одинаковыми для java.яз..Строковые объекты в Scala. Это означает, что две строки, содержащие val
s, не должны быть равными ссылкам, даже если их строки идентичны. Но вот что я получаю в 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 ответа:
Да, это магия компилятора. В частности, это называетсяинтернирование . Java делает это также, и это просто из соображений эффективности, таких как использование памяти и возможность сравнения без сравнения каждого символа. Вот статья в Википедии об этом . Вы также можете интернировать строки вручную с помощью метода
intern()
.
Из спецификации языка Java :
Строковый литерал-это ссылка на экземпляр класса
String
(§4.3.1, §4.3.3).Более того, строковый литерал всегда ссылается на один и тот же экземпляр класса
String
. Это происходит потому, что строковые литералы - или, более широко, строки, которые являются значениями постоянных выражений (§15.28) - "интернируются", чтобы совместно использовать уникальные экземпляры, используя методString.intern
.