2012-04-09 8 views
5

Uno esperaría que, aunque las cadenas son inmutables, value-equality y reference-equality no serían las mismas para los objetos java.lang.String en Scala. Esto significa que dos cadenas que contienen val s no deben ser de referencia, incluso cuando sus cadenas son idénticas. Pero esto es lo que me pasa en un REPL 2.9.1.final:Igualdad de referencia para java.lang.String en 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 

Cualquier idea de por qué el resultado no fue false? El mismo experimento con List("a") en lugar de "a" funciona como se esperaba. El método eq está marcado como final en AnyRef. ¿Hay alguna magia de compilación hecha específicamente para String o java.lang.String?

Respuesta

13

Sí, es compilador mágico. Específicamente, se llama interna. Java también lo hace, y es simplemente por razones de eficiencia, como el uso de memoria y permitir comparaciones sin comparar cada personaje. Aquí hay un Wikipedia article on it. También puede internar cadenas manualmente con el método intern().

4

Desde el Java language specification:

Una cadena literal es una referencia a una instancia de la clase String (§4.3.1, §4.3.3).

Por otra parte, una cadena literal siempre se refiere a la misma instancia de la clase String. Esto se debe a que los literales de cadena (o, más generalmente, las cadenas que son los valores de las expresiones constantes (§15.28)) son "internados" para compartir instancias únicas, usando el método String.intern.

+0

Gracias! Curiosamente, cuando cambio mi ejemplo, empiezo con 'val s1 =" aa "; val s2 = "a" + "a" ', el resultado sigue siendo el mismo, aunque' "a" + "a" 'no es una expresión constante (¿verdad?). Entonces parece que Scala hace un poco más de lo que dice la especificación de Java. –

+3

'" a "+" a "' ** es ** una expresión constante, consulte [Expresiones constantes] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html # jls-15.28) – fredoverflow

+1

Las especificaciones de Java para expresiones constantes no parecen ser exactamente las mismas para Scala. Por ejemplo, usando uno de los ejemplos dados en esa página de Expresiones constantes, '" El entero "+ java.lang.Long.MAX_VALUE +" es muy grande. '' No está intercalado por scalac. –

Cuestiones relacionadas