Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

307
Visualizações
Comportamiento extraño con la internación de cadenas en Java

Hay un código de la siguiente manera:

 String s = new String("1"); s.intern(); String s2 = "1"; System.out.println(s == s2); String s3 = new String("1")+new String("1"); s3.intern(); String s4 = "11"; System.out.println(s3 == s4);

La salida del código anterior es:

 false true

Sé que s y s2 son objetos diferentes, por lo que el resultado se evalúa como falso, pero el segundo resultado se evalúa como verdadero. ¿Alguien puede decirme la diferencia?

about 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Esto es lo que está pasando:


Ejemplo 1

 String s1 = new String("1"); s1.intern(); String s2 = "1";
  1. El literal de cadena "1" (pasado al constructor de String ) está internado en la dirección A .
    La cadena s1 se crea en la dirección B porque no es una expresión literal o constante.
  2. La llamada a intern() no tiene efecto. La cadena "1" ya está interna y el resultado de la operación no se vuelve a asignar a s1 .
  3. La cadena s2 con el valor "1" se recupera del grupo de cadenas, por lo que apunta a la dirección A .

Resultado: las cadenas s1 y s2 apuntan a direcciones diferentes .


Ejemplo 2

 String s3 = new String("1") + new String("1"); s3.intern(); String s4 = "11";
  1. La cadena s3 se crea en la dirección C.
  2. La llamada a intern() agrega la cadena con el valor "11" en la dirección C al grupo de cadenas.
  3. La cadena s4 con el valor "11" se recupera del grupo de cadenas, por lo que apunta a la dirección C .

Resultado: las cadenas s3 y s4 apuntan a la misma dirección.


Resumen

La cadena "1" se interna antes de que se realice la llamada a intern() , en virtud de su presencia en la llamada al constructor s1 = new String("1") .

Cambiar esa llamada al constructor a s1 = new String(new char[]{'1'}) hará que la comparación de s1 == s2 se evalúe como verdadera porque ambos ahora se referirán a la cadena que se internó explícitamente llamando a s1.intern() .

(Utilicé el código de esta respuesta para obtener información sobre las ubicaciones de memoria de las cadenas).

about 4 years ago · Santiago Trujillo Relatório

0

Para el escenario 1:

 String s = new String("1"); s.intern(); String s2 = "1"; System.out.println(s == s2);

con código de bytes :

 0: new #2 // class java/lang/String 3: dup 4: ldc #3 // String 1 6: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V 9: astore_1 10: aload_1 11: invokevirtual #5 // Method java/lang/String.intern:()Ljava/lang/String; 14: pop 15: ldc #3 // String 1

para String s = new String("1"); creará un nuevo objeto String , tendrá una nueva dirección con "1" que ya está en String Pool :

ldc #3 // String 1

y para s2 , como el código de bytes:

15: ldc #3 // String 1

s2 apunta a la variable String Pool : "1" , por lo que s y s2 tienen direcciones diferentes y el resultado es false .

Para el escenario 2:

 String s3 = new String("1")+new String("1"); s3.intern(); String s4 = "11"; System.out.println(s3 == s4);

con código de bytes :

 0: new #2 // class java/lang/StringBuilder 3: dup 4: invokespecial #3 // Method java/lang/StringBuilder."<init>":()V 7: astore_1 8: aload_1 9: ldc #4 // String 1 11: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 14: ldc #4 // String 1 16: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 19: invokevirtual #6 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 22: astore_2 23: aload_2 24: invokevirtual #7 // Method java/lang/String.intern:()Ljava/lang/String; 27: astore_3 28: ldc #8 // String 11

Como código de bytes , puede ver new String("1")+new String("1"); se crea usando StringBuilder

new #2 // class java/lang/StringBuilder

es totalmente un objeto nuevo sin la variable String Pool .

y después de s3.intern() , este método agregará s3 actual al grupo de cadenas de memoria y 8: aload_1 .

y s4 está intentando cargar desde

ldc #8 // String 11

por lo tanto, las direcciones s3 y s4 deben ser iguales y el resultado es verdadero.

about 4 years ago · Santiago Trujillo Relatório

0

Solo para alguien que usa groovy, la información adicional es: el comportamiento es diferente

ingrese la descripción de la imagen aquí

about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda