strings numeros manejo evaluar español effective edition edición condicionales condicional con comparar como cadenas cadena 3rd 3ra java string specifications effective-java

numeros - java condicional string



¿Cómo la JVM reutiliza subcadenas String internas? (3)

Soy consciente de que si haces

for (condition) { String s = "hi there"; }

Solo se crea una instancia de String en todas las iteraciones, a diferencia de String s = new String("hi there"); Eso creará una nueva instancia en cada iteración.

Pero, leyendo Eficaz Java de Joshua Bloch: Capítulo 2, Artículo 5 (página 20), dice:

Además, se garantiza que el objeto será reutilizado por cualquier otro código que se ejecute en la misma máquina virtual que contenga la misma cadena literal [JLS, 3.10.5] .

AFAIK que no dice que es la misma cadena literal , dice que contiene .

La lectura [JLS, 3.10.5] no puede encontrar ninguna referencia exacta a esto y tengo una duda.

Dando este fragmento:

String s1 = "hi "; String s2 = "there"; String s3 = "hi there";

¿Cuántas instancias se crean?

  • 3 instancias (por lo tanto, la frase no es realmente exacta).
  • 2 instancias, s1 y s2 (luego se crea s3 reutilizando las referencias s1 y s2 )

Cada archivo de clase contiene una lista de todos los literales de cadena u otras constantes utilizadas dentro de esa clase (excepto las constantes numéricas pequeñas que están incrustadas dentro del flujo de instrucciones). Si el elemento 19 en la lista es la cadena literal "Freddy" , y la variable local Fred tiene un índice de 6, entonces el bytecode generado para Fred="Freddy"; probablemente sería ldc 19 / astore 6 .

Cuando se carga una clase, el sistema creará una tabla con todas las constantes y, para aquellos de tipo de referencia, los objetos identificados de ese modo. Si no se sabe que exista una instancia de una cadena literal, el sistema agregará uno a la tabla de internado y almacenará una referencia a eso. Cuando se genera un código de máquina, el ldc 19 se reemplazará con una instrucción para cargar la referencia apropiada.

Lo importante es que, para cuando se ejecuta cualquiera de los códigos en una clase, se han creado objetos para todos los literales de cadena, así que una declaración como Fred="Freddy"; simplemente almacenará una referencia a un objeto String ya existente que contiene Freddy , en lugar de crear un nuevo objeto String .


El JLS no garantiza la reutilización de las subcadenas de ningún tipo. El "contenido" aquí significa simplemente que la clase menciona exactamente la misma cadena literal en algún lugar. No se usa en la "subcadena de" sentido.


Si s3 reutilizó las instancias s1 y s2 , entonces s3 no se representaría físicamente como una matriz de caracteres continua, sino que sería una String compuesta de objetos de String .

Ahora imagine el impacto en el rendimiento al acceder a caracteres individuales dentro de una cadena de este tipo: el acceso basado en índice implicaría realmente comparar el valor del índice con el tamaño de la primera cadena, luego el cálculo del desplazamiento que se convertiría en índice para la segunda cadena, etc.

En realidad, lo opuesto podría tener sentido: solo se podría asignar una secuencia char subyacente para "hi there" ( s3 ), y s1 y s2 solo podrían almacenar sus longitudes y direcciones del primer carácter dentro de esa cadena. Pero asumo que sería un trabajo complejo y costoso para jvm identificar a los candidatos que se "integran" y que el costo superaría el beneficio potencial.