2009-12-13 22 views
5
public class A { 

    static String s1 = "I am A"; 

    public static void main(String[] args) { 
     String s2 = "I am A"; 
     System.out.println(s1 == s2); 
    } 
} 

El programa anterior muestra "verdadero". Ambos son dos identificadores/objetos diferentes, ¿cómo la salida es "verdadera"?Pregunta básica de Java: igualdad de cadenas

Mi entendimiento es que la JVM se crean diferentes de referencia para cada objeto, si es así cómo la salida es cierto?

Respuesta

20

Java gestiona una agrupación literal String. Reutiliza estos literales cuando puede. Por lo tanto, los dos objetos son en realidad el mismo objeto String y == devuelve verdadero.

Creo que esto se llama string interning

+1

Para obtener información sobre el grupo de cadenas, eche un vistazo a la wikipedia: http://en.wikipedia.org/wiki/String_interning (+1 misma idea) –

+1

Sí, los literales de cadenas se internan automáticamente, según el método interno API - http : //java.sun.com/javase/6/docs/api/java/lang/String.html – Ash

+1

No son solo literales internados, sino también constantes de tiempo de compilación. –

1

No están comparando el contenido de las cuerdas. Solo está comparando las referencias del objeto. Debe usar el método igual (que es un miembro de la clase String). O eso o puede usar el método compareTo (también bajo la misma clase de String) para verificar si el valor de retorno es cero.

Tenga en cuenta el texto anterior era más de una sugerencia fuerte para el estado original de la pregunta que apareció el PO no estaba al tanto del proceso real pasando detrás de las escenas.

Los otros chicos que sugieren internalling era correcto. Para responder a esta pregunta, no tuve tiempo suficiente para acceder al libro de Java Puzzlers. Sospeché algo acerca de establecer la misma referencia en tiempo de compilación, pero tampoco sabía cómo encontrar una referencia a eso.

+0

Si se compara el contenido, entonces la respuesta es definitivamente 'verdadero' Pero aquí ambos son dos variables diferentes, ganaron 't jvm crea dos referencias diferentes? – novice

+1

@Felix. No, él está comparando referencias, y la salida es verdadera, que es exactamente el resultado ligeramente sorprendente que ha provocado esta pregunta. –

+2

¿Por qué ustedes mar ked una respuesta correcta? –

5

Debido a que el Java Language Specification dice: literales o

de Cuerda, de manera más general, cadenas que son los valores de expresiones constantes (§15.28) -son "interned" para compartir instancias únicas , utilizando el método String.intern.

6

== comprueba que las variables apuntan a la misma instancia exacta de un objeto. Los dos literales de cadena que ha creado apuntan al mismo lugar en la memoria y, por lo tanto, son iguales. Los literales de cadena están internados de manera que el mismo literal de cadena sea el mismo objeto en la memoria.

Si se va a hacer

String s = new String("foo"); 
String t = new String("foo"); 

== Luego volvería falsa y s.equals (t) devolvería cierto.

5

Es debido a una optimización de la memoria realizada por el compilador ... a saber, String constantes (es decir, - String s hechas por el mismo String literal) utilizan el mismo objeto desde StringStrings son inmutables. El operador == simplemente comprueba que dos objetos son el mismo objeto real.

Si puedes agarrar el libro Java Puzzlers de Joshua Bloch y Neal Gafter, y mira el rompecabezas 13, "Animal Farm" ... él tiene buenos consejos sobre este tema. Voy a copiar un texto relevante:

"Usted puede ser consciente de que las constantes de tiempo de compilación de tipo String internadas [JLS 15.28] En otras palabras, las dos expresiones constantes de tipo String que designan la misma secuencia de caracteres son. representado por referencias de objeto idénticas ...Su código rara vez, si es que alguna vez, depende del internamiento de constantes de cadena. El internamiento se diseñó únicamente para reducir la huella de memoria de la máquina virtual, no como una herramienta para programadores ... Al comparar referencias de objetos, debe usar el método equals con preferencia al operador == a menos que necesite comparar identidad de objeto en lugar de valor .."

Eso es de la referencia anterior he mencionado ... páginas 30 -. 31 en mi libro

+1

Mencioné esto [concedido que no mencioné por qué lo hizo], y me votaron a favor. – monksy

+0

+1 Por mencionar Puzzlers y una explicación de por qué – monksy

Cuestiones relacionadas