Considere los siguientes dos programas Java, el primer programa produce una salida como «Sí», pero el segundo programa produce una salida «No». ¿Puedes adivinar la razón?
// Program 1: Comparing two references to objects // created using literals. import java.util.*; class GFG { public static void main(String[] args) { String s1 = "abc"; String s2 = "abc"; // Note that this == compares whether // s1 and s2 refer to same object or not if (s1 == s2) System.out.println("Yes"); else System.out.println("No"); } }
Yes
// Program 2: Comparing two references to objects // created using new operator. import java.util.*; class GFG { public static void main(String[] args) { String s1 = new String("abc"); String s2 = new String("abc"); // Note that this == compares whether // s1 and s2 refer to same object or not if (s1 == s2) System.out.println("Yes"); else System.out.println("No"); } }
No
Entendamos por qué obtenemos resultados diferentes con la siguiente explicación.
String es una secuencia de caracteres. Una de las características más importantes de una string en Java es que son inmutables. En otras palabras, una vez creada, el estado interno de una string permanece igual durante la ejecución del programa. Esta inmutabilidad se logra mediante el uso de un conjunto de constantes de string especial en el montón. En este artículo, entenderemos sobre el almacenamiento de las strings.
Un grupo de constantes de string es un lugar separado en la memoria del montón donde se almacenan los valores de todas las strings definidas en el programa. Cuando declaramos una string, se crea un objeto de tipo String en la pila, mientras que una instancia con el valor de la string se crea en el montón. En la asignación estándar de un valor a una variable de string, la variable se asigna a la pila, mientras que el valor se almacena en el montón en el conjunto de constantes de string. Por ejemplo, asignemos algún valor a una string str1. En java, se define una string y el valor se asigna como:
String str1 = "Hello";
La siguiente ilustración explica la asignación de memoria para la declaración anterior:
En el escenario anterior, se crea un objeto de string en la pila y el valor «Hola» se crea y almacena en el montón. Dado que normalmente hemos asignado el valor, se almacena en el área de almacenamiento constante del montón. Un puntero apunta hacia el valor almacenado en el montón del objeto en la pila. Ahora, tomemos el mismo ejemplo con varias variables de string que tienen el mismo valor de la siguiente manera:
String str1 = "Hello"; String str2 = "Hello";
La siguiente ilustración explica la asignación de memoria para la declaración anterior:
En este caso, ambos objetos de string se crean en la pila, pero no se crea otra instancia del valor «Hola» en el montón. En su lugar, se reutiliza la instancia anterior de «Hola». El grupo de constantes de string es un pequeño caché que reside dentro del montón. Java almacena todos los valoresdentro del grupo de constantes de string en la asignación directa. De esta manera, si se necesita acceder nuevamente a un valor similar, un nuevo objeto de string creado en la pila puede hacer referencia a él directamente con la ayuda de un puntero. En otras palabras, el grupo de constantes de string existe principalmente para reducir el uso de la memoria y mejorar la reutilización de las instancias existentes en la memoria. Cuando a un objeto de string se le asigna un valor diferente, el nuevo valor se registrará en el conjunto de constantes de string como una instancia separada. Entendamos esto con el siguiente ejemplo:
String str1 = "Hello"; String str2 = "Hello"; String str3 = "Class";
La siguiente ilustración explica la asignación de memoria para la declaración anterior:
Una forma de omitir esta asignación de memoria es usar la nueva palabra clave al crear un nuevo objeto de string. La palabra clave ‘nuevo’ obliga a que siempre se cree una nueva instancia, independientemente de si el mismo valor se usó anteriormente o no. El uso de ‘nuevo’ obliga a que la instancia se cree en el montón fuera del grupo de constantes de string, lo cual está claro, ya que aquí no se permite el almacenamiento en caché ni la reutilización de instancias. Entendamos esto con un ejemplo:
String str1 = new String("John"); String str2 = new String("Doe");
La siguiente ilustración explica la asignación de memoria para la declaración anterior:
Publicación traducida automáticamente
Artículo escrito por ArkadyutiBanerjee y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA