que - tipos de variables en java ejemplos
Preguntas sobre el grupo de cadenas de Java (7)
Considera este código:
String first = "abc";
String second = new String("abc");
Al usar la new
palabra clave, Java creará la String
abc
nuevo, ¿verdad? ¿Se almacenará esto en el montón común o en el grupo de String
? ¿Cuántas String
terminarán en el grupo de String
?
Aunque tarde, puede ser útil para alguien que todavía se encuentre con esto:
String first = "abc";
//One instance object in pool created. Instance variable “first” refers/points to pooled object
String second = new String("abc");
//One instance object in heap created. Object in pool creation step will be skipped on account of first statement.
Entonces, en total se crearán 2 objetos instancia. Uno en el grupo y otro en montón
Explicación detallada
String first = "abc";
Aquí un objeto de cadena con contenido "abc" creado en el grupo. La variable de instancia "first" apuntará al objeto pool con el contenido "abc".
String second = new String ("abc");
Aquí se creará en heap otro objeto de cadena con contenido "abc". La variable de instancia "segundo" apuntará al objeto de montón con contenido "abc". Se omitirá un objeto de cadena con creación de contenido "abc" en el grupo a causa de la primera instrucción. Razón a continuación
Razones
Si se asume una declaración anterior (String first = "abc";) no está allí con el mismo contenido, generalmente con la palabra clave "nueva", se crearán 2 objetos de cadena uno en montón (grupo externo) y el otro en grupo (un área subconjunto de montón). Además, la variable de instancia "segundo" debe apuntar a objeto de montón solamente, independientemente de si los objetos están en el grupo o no.
Ahora, debido a la presencia del enunciado anterior (String first = "abc";) con el mismo contenido que en el nuevo String ("abc"), solo un objeto (con contenido "abc") se conserva en el grupo. Entonces, a causa de la primera declaración, la segunda declaración tendrá solo 1 objeto creado en lugar de 2 y ese objeto estará en montón. La creación de objetos de grupo se saltará.
//Additional Test on the concept
System.out.println(first==second); //returns false. Because first points to pool object while second points to heap object. And both objects are different (on account of different memory locations).
second = second.intern(); //After interning, second now points to pool object. Note: intern is used so that reference variable points to pool area object and not heap object. Clearly it is applicable when we use new keyword.
System.out.println(first==second); //returns true. Because now both first and second objects now points to same pool object.
Cada vez que su código crea un literal de cadena
por ejemplo:
String str="Hello"; (string literal)
la JVM comprueba primero el grupo de cadenas literales. Si la cadena ya existe en el conjunto, vuelve a aparecer una referencia a la instancia agrupada. Si la cadena no existe en el conjunto, un nuevo objeto String crea una instancia, luego se coloca en el grupo. Java puede hacer esta optimización ya que las cadenas son inmutables y se pueden compartir sin temor a daños en los datos.
En bytecode , la primera tarea es:
Code: 0: ldc #2; //String abc 2: astore_1
mientras que el segundo es:
3: new #3; //class java/lang/String 6: dup 7: ldc #2; //String abc 9: invokespecial #4; //Method java/lang/String."":(Ljava/lang/String;)V
Entonces, el primero está en el grupo (en la posición # 2) mientras que el segundo se almacenará en el montón.
EDITAR
Como CONSTANT_String_info
almacena el índice como U2 (16 bits, sin signo), el grupo puede contener como máximo 2**16
= 65535
referencias. En el caso, aquí le importan más los límites de la JVM .
La única vez que debe usar un nuevo String (foo) es cuando desea romper ==, que es un caso extraño, o cuando foo es una subcadena de una cadena mucho más grande que tiene una vida útil limitada, como
String mystring;
{
String source = getSomeHeinouslyLargeString();
mystring = new String(source.substring(1,3));
}
Si usa la palabra clave nueva, se creará un nuevo objeto String
. Tenga en cuenta que los objetos siempre están en el montón: el grupo de cadenas no es un área de memoria separada que está separada del montón.
El grupo de cadenas es como un caché. Si haces esto:
String s = "abc";
String p = "abc";
entonces el compilador de Java es lo suficientemente inteligente como para hacer un solo objeto String
, y s
y p
referirán a ese mismo objeto String. Si haces esto:
String s = new String("abc");
luego habrá un objeto String
en el grupo, el que representa el literal "abc"
, y habrá un objeto String
separado, no en el grupo, que contiene una copia del contenido del objeto agrupado. Dado que String
es inmutable en Java, no obtendrás nada al hacer esto; Llamar a una new String("literal")
nunca tiene sentido en Java y es innecesariamente ineficiente.
Tenga en cuenta que puede llamar a intern()
en un objeto String
. Esto colocará el objeto String
en el grupo si aún no está allí, y devolverá la referencia a la cadena agrupada. (Si ya estaba en el grupo, simplemente devuelve una referencia al objeto que ya estaba allí). Consulte la documentación de API para ese método para obtener más información.
Véase también Interno de cadenas (Wikipedia).
String first = "abc";
String second = new String("abc");
En el primer caso, solo se creará un objeto en Pool. En el segundo caso, dos objetos crearán uno en el grupo (si esto no existe previamente en el grupo) y otro en el montón.
Cuando está pasando cualquier valor con comillas dobles ex: "abc" está creando un objeto en el grupo y pasándolo al constructor de cadenas para crear un nuevo objeto con el mismo valor en el montón.
Si vio el constructor de cadenas, puede ver que acepta una cadena. ¿Qué es esa cuerda? Antes de la creación, ¿qué es ese objeto de cadena? No es más que un objeto almacenado en el conjunto de String Constant.
String strObject = new String("Java");
y
String strLiteral = "Java";
Ambas expresiones te dan el objeto String, pero hay una sutil diferencia entre ellas. Cuando crea un objeto String utilizando el operador new (), siempre crea un nuevo objeto en la memoria del montón. Por otro lado, si crea un objeto usando la sintaxis literal String, por ejemplo, "Java", puede devolver un objeto existente de String pool (un caché de objeto String en el espacio generador de Perm, que ahora se mueve al espacio libre en la versión Java reciente) , si ya existe