2012-04-09 2 views
5

Можно было бы ожидать, что хотя строки неизменяемы, равнозначность равенства и ссылочное равенство не будут одинаковыми для объектов java.lang.String в Scala. Это означает, что два удерживающих строки val s не должны быть ссылочными, даже если их строки идентичны. Но вот что я получаю в 2.9.1.final РЕПЛ:Ссылка на равенство для java.lang.String в Scala

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?

ответ

13

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

4

От Java language specification:

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

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

+0

Спасибо! Интересно, что, когда я изменяю свой пример, чтобы начать с 'val s1 =" aa "; val s2 = "a" + "a" ', результат все тот же, хотя' 'a" + "a" 'не является постоянным выражением (это?). Таким образом, похоже, что Scala немного больше, чем говорит спецификация Java. –

+3

'' a "+" a "' ** ** является постоянным выражением, см. [Constant Expressions] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html # jls-15.28) – fredoverflow

+1

Спецификация Java для постоянных выражений не кажется точно такой же для Scala. Например, используя один из примеров, приведенных на этой странице Constant Expressions, «Целое число» + java.lang.Long.MAX_VALUE + «очень велико». 'Не интернировано с помощью scalac. –

Смежные вопросы