java - ¿Cuándo cambia la piscina?
string pool (3)
¿Por qué s1 y s2 apuntan al mismo objeto, mientras que s1 y s3 no lo hacen? (No hay uso de nueva palabra clave).
Dado que las String
en Java son Immutable
, cualquier método de clase de cadena devolverá un nuevo objeto de cadena (aunque hay alguna excepción, sin embargo, una es el método de substring
). Por lo tanto, el método concat
crea una nueva cadena, que va al montón y no se agrega a la agrupación constante.
En lo que respecta al caso de s1
y s2
, ambas cadenas se conocen en tiempo de compilación y, por lo tanto, son iguales literales de cadena.
Tenga en cuenta que la operación de concatenación en la 2ª cadena:
String s2 = "b" +"l" + "a";
se evalúa en el momento de la compilación, y se sabe que el resultado es el mismo que el de la primera cadena, y se hace una entrada a la agrupación constante.
Tengo dos preguntas:
public static void main(String[] args) {
String s1 = "bla";
String s2 = "b" +"l" + "a";
String s3 = "b".concat("l").concat("a");
if(s1 == s2)
System.out.println("Equal");
else
System.out.println("Not equal");
if(s1 == s3)
System.out.println("Equal");
else
System.out.println("Not equal");
}
¿Por qué
s1
ys2
apuntan al mismo objeto, mientras ques1
ys3
no lo hacen? ( No hay uso denew
palabra clave ).Si obtengo una cadena del usuario y agrego estas líneas al código anterior:
BufferedReader in=new BufferedReader(new InputStreamReader(System.in)); String name=in.readLine(); if(name.equals("test")) s1 = s1 + "xyz";
Si el usuario ingresa
xyz
el programa imprimiráNot equal
, cuando el usuario ingrese otra cosa, el programa emitiráEqual
. ¿Significa esto que la piscina cambia a través de la ejecución de todo el programa? ¿El optimizador funciona en el momento de la compilación y continúa funcionando en elruntime
?
¿Por qué s1 y s2 apuntan al mismo objeto, mientras que s1 y s3 no lo hacen? (No hay uso de nueva palabra clave).
Debido a que la concatenación ocurre en el momento de la compilación, y la cadena completa, por lo tanto, va en el conjunto constante igual que en el primer ejemplo. Es un caso especial "conocido" para el compilador. Realmente significa que las cadenas largas, concatenadas de esta manera en varias líneas, aún se benefician de las mismas mejoras de rendimiento que las constantes de cadena simples.
En el segundo ejemplo, está realizando el cálculo en tiempo de ejecución, por lo que no formará parte de la agrupación constante.
Sin embargo, tenga en cuenta que en el JLS los detalles de lo que puede y no puede ir en el conjunto de constantes de cadena se dejan deliberadamente imprecisos, por lo que diferentes implementaciones pueden optimizar de diferentes maneras. Especifica ciertas reglas en cuanto a lo que debe ir allí, pero no confíe en que este comportamiento sea consistente en todas las implementaciones.
A veces (cuando es evidente para el compilador cuál es el valor de una cadena en el tiempo de ejecución) el compilador usa el grupo de cadenas, en otros casos no lo hace.
En realidad, su código no debe depender del hecho de usar o no el grupo.
No siempre puede ejecutar main, por lo tanto, si desea ver si su String se usa desde el pool, puede descompilar el código con javap, el listado es relativamente autoexplicativo.