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