2012-09-09 15 views
7

me encontré el siguiente programa,problemas cadena de Java

String firstString = "String"; 
    String secondString = "String"; 
    String thirdString = new String("String"); 
    System.out.println(firstString == secondString); 
    System.out.println(firstString == thirdString); 
    System.out.println(firstString.intern() == thirdString); 
    System.out.println(firstString.intern() == thirdString.intern()); 
    System.out.println(firstString.intern().equals(thirdString.intern())); 
    System.out.println(firstString == thirdString); 

y mi salida fue

true 
false 
false 
true 
true 
false 

supe que la cadena de piscinas con JVM mismo contenido que mismas cadenas. ¿Está bien? Si eso es cierto, ¿por qué no firstString == thirdString return false? ¿Jvm solo agrupa la cadena solo inicializada con: "" y no con un nuevo operador?

+0

Pruebe también: 'firstString == thirdString.intern()', para ver que los literales de cadena se internalizan automáticamente. –

Respuesta

6

La agrupación se refiere solo a literales de cadenas, por lo que firstString y secondString son en realidad el mismo objeto, donde como en thirdString solicitó explícitamente la creación de un nuevo objeto en el montón.

Recomiendo leer la sección sobre string literals in the spec.

Proporciona más información sobre cómo y cuándo se combinan las cadenas.

Además, tenga en cuenta que estas balas al final de la sección:

  • Las cadenas literales de la misma clase (§ 8) en el mismo paquete (§ 7) representan referencias a la misma cadena objeto (§4.3.1).
  • Las cadenas literales dentro de diferentes clases en el mismo paquete representan referencias al mismo objeto String.
  • Las cadenas literales dentro de diferentes clases en diferentes paquetes también representan referencias al mismo objeto String.
  • Las cadenas calculadas mediante expresiones constantes (§15.28) se calculan en tiempo de compilación y luego se tratan como si fueran literales.
  • Las cadenas calculadas por concatenación en tiempo de ejecución se crean por última vez y, por lo tanto, son distintas.
+0

De acuerdo, acepto sus explicaciones. Creé un nuevo objeto como thirdObject con "String" en heap. Lo he internado. Entonces en la piscina habrá dos objetos ¿verdad? La primera y la segunda cadena se referirán al objeto A (para citación) y la tercera referirá otra (B). – vvekselva

0

thirdString no es de la piscina. No es un literal de cadena, lo creó dinámicamente con el operador new.

secondString por el contrario, se toma del grupo (le asigna una cadena literal), por lo que el mismo objeto se asigna a firstString y secondString.

-1

"firstString == thirdString" devuelve falso.

El método interno "devuelve una representación canónica para el objeto de cadena". Si asigna la cadena de internación:

thirdString=thirdString.intern(); 

última "firstString == thirdString" devuelve verdadero

2

Para firstString y secondString, JVM buscar el grupo de cadena y devolver la referencia de "Cadena".

Para thirdString, JVM no buscará el grupo de cadenas y solo creará un objeto String en el montón.

Para OneString.intern(), JVM buscará la referencia en el grupo de cadenas, agregará OneString al conjunto de cadenas si OneString no existe en él, y devolverá la referencia.

+0

Tengo una consulta, agregando objetos (cadena) en el grupo se basa en el hash del objeto o el contenido del objeto (representación canónica). El interno llamante agregará al grupo y devolverá la representación canónica, lo que significa que toda la cadena debe referirse al mismo, ya que todos tienen la misma representación canónica. – vvekselva

+0

Después de llamar a intern(), la cadena se agregará al grupo de cadenas y el objeto Cadena se referirá a la nueva referencia de cadena en el grupo de cadenas. El objeto cadena original será recolectado por GC la próxima vez. –

+0

¿Hay alguna forma de perfilar esto? Solo quiero verificar los contenidos del grupo de pasantes? ¿Hay alguna manera? – vvekselva