Ссылочное равенство для java.lang.String в Scala

Можно было бы ожидать, что даже если строки неизменны, равенство значений и равенство ссылок не будут одинаковыми для объектов java.lang.String в 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 ответа

Решение

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

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

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

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

Другие вопросы по тегам