JavaRush /Blog Java /Random-ES /Traducción: ¿Crear objetos String en Java - usando " " o ...
FellowSparrow
Nivel 12
Lvov

Traducción: ¿Crear objetos String en Java - usando " " o constructor?

Publicado en el grupo Random-ES
Original: ¿Crear una cadena Java usando “ ” o Constructor? Por X Wang Traducción: Creación de objetos de cadena en Java - UsoEn Java, se pueden crear cadenas utilizando dos métodos:
String x = "abc";
String y = new String("abc");
¿Cuál es la diferencia entre usar comillas dobles y usar un constructor?

1. Comillas dobles vs. Constructor

Esta pregunta puede responderse observando dos ejemplos sencillos. Ejemplo 1:
String a = "abcd";
String b = "abcd";
System.out.println(a == b);  // True
System.out.println(a.equals(b)); // True
a==bEs cierto porque aambos bse refieren al mismo objeto: una cadena declarada como literal (literal de cadena a continuación) en el área del método (remitimos al lector a la fuente de nuestro recurso: Los 8 diagramas principales para comprender Java , diagrama 8). Cuando el mismo literal de cadena se crea más de una vez, solo se almacena una copia de la cadena en la memoria, solo una instancia de la misma (en nuestro caso, "abcd"). Esto se llama "internación de cadenas". Todas las constantes de cadena procesadas en tiempo de compilación se internan automáticamente en Java. Ejemplo 2:
String c = new String("abcd");
String d = new String("abcd");
System.out.println(c == d);  // False
System.out.println(c.equals(d)); // True
c==dfalso porque cse drefieren a dos objetos diferentes en la memoria (en el montón). Diferentes objetos siempre tienen diferentes referencias. Este diagrama ilustra las dos situaciones descritas anteriormente: Traducción: Creación de objetos de cadena en Java - Uso

2. Cadenas internas en la etapa de ejecución del programa.

El autor agradece a LukasEder (el comentario a continuación es suyo): El internamiento de cadenas también puede ocurrir durante la ejecución del programa, incluso si se crean dos cadenas usando constructores:
String c = new String("abcd").intern();
String d = new String("abcd").intern();
System.out.println(c == d);  // Now true
System.out.println(c.equals(d)); // True

3. Cuándo usar comillas dobles y cuándo usar constructores

Debido al hecho de que el literal "abcd" siempre es de tipo String, el uso de un constructor creará un objeto adicional innecesario. Por lo tanto, se deben usar comillas dobles si solo necesita crear una cadena. Si realmente necesitas crear un nuevo objeto en el montón, debes usar un constructor. Los casos de uso se muestran aquí (original) . (Proporciono el texto traducido a continuación. Pero aun así recomiendo encarecidamente que se familiarice con el código de los comentaristas en este enlace).

El método substring() en JDK 6 y JDK 7

El método substring() en JDK 6 y JDK 7 por X Wang El método substring(int beginIndex, int endIndex)en JDK 6 y JDK 7 es diferente. Conocer estas diferencias puede ayudarle a utilizar mejor este método. Para facilitar la lectura, a continuación substring()nos referiremos a la sintaxis completa, es decir. substring(int beginIndex, int endIndex).

1. ¿Qué hace la subcadena()?

El método substring(int beginIndex, int endIndex)devuelve una cadena que comienza con el número de carácter beginIndexy termina con el número de carácter endIndex-1.
String x = "abcdef";
x = x.substring(1,3);
System.out.println(x);
Producción:
bc

2. ¿Qué sucede cuando se llama a substring()?

Quizás sepas que, debido a la inmutabilidad x, al asignar a x el resultado de x.substring(1,3), xapunta a una fila completamente nueva (ver diagrama): Traducción: Creación de objetos de cadena en Java - UsoSin embargo, este diagrama no es completamente correcto; no demuestra lo que realmente está sucediendo en el montón. Lo que realmente sucede cuando se llama substring()es diferente en JDK 6 y JDK 7.

3. subcadena() en JDK 6

El tipo de cadena es compatible con el tipo de matriz char. En JDK 6, la clase Stringcontiene 3 campos: char value[], int offset, int count. Se utilizan para almacenar la matriz real de caracteres, el índice del primer carácter de la matriz y el número de caracteres en la línea. Cuando se llama al método substring(), crea una nueva fila, pero el valor de la variable aún apunta a la misma matriz en el montón. La diferencia entre dos cadenas es su número de caracteres y el valor de índice del carácter inicial de la matriz. Traducción: Creación de objetos de cadena en Java - UsoEl siguiente código está simplificado y solo contiene lo básico para demostrar el problema.
//JDK 6
String(int offset, int count, char value[]) {
	this.value = value;
	this.offset = offset;
	this.count = count;
}

public String substring(int beginIndex, int endIndex) {
	//check boundary
	return  new String(offset + beginIndex, endIndex - beginIndex, value);
}

4. Problema causado por substring() en JDK 6

Si tiene una cadena MUY larga, pero solo necesita una pequeña parte, que obtiene cada vez que usa substring(). Esto causará problemas de ejecución, ya que solo necesitas una pequeña parte, pero aún así debes almacenar la cadena completa. Para JDK 6, la solución es el siguiente código, que convertirá la cadena en una subcadena real:
x = x.substring(x, y) + ""
El usuario STepeR formuló una pregunta (ver su comentario), y pareció necesario añadir el punto 4. "Problema causado substring()en JDK 6" es un ejemplo más extenso. Espero que esta sea la respuesta y ayude a otros a descubrir rápidamente cuál es el problema. Aquí está el código:
String a = "aLongLongString";
String b = a.substring(1, 2);
String c = a.substring(2, 6);
Entonces, en JDK 7 b, los objetos сde tipo a Stringcreados llamando a un método substring()en un objeto de tipo a Stringharán referencia a dos matrices recién creadas en el montón: Lfor b, ongLfor c. Estas dos nuevas matrices se almacenarán en el montón JUNTO con la matriz original aLongLongStringa la que hace referencia a. Aquellos. la matriz original no desaparece por ningún lado. Ahora volvamos a JDK 6. En JDK 6, un montón contiene una única matriz aLongLongString. Después de ejecutar las líneas de código.
String b = a.substring(1, 2);
String c = a.substring(2, 6);
los objetos bse refieren ca la misma matriz en el montón, correspondiente al objeto a: b- a los elementos del 1.º índice al 2.º, c- a los elementos del 2.º índice al 6.º (la numeración comienza desde 0, recordatorio). Aquellos. Obviamente, cualquier acceso adicional a las variables bo c en JDK 6 en realidad dará como resultado que los elementos deseados de la matriz original se "cuenten" en el montón. En JDK 7, cualquier acceso adicional a variables bo c provocará un acceso a las matrices más pequeñas necesarias que ya se han creado y "viven" en el montón. Aquellos. Claramente, JDK 7 usa físicamente más memoria en situaciones como esta. Pero imaginemos una posible opción: ciertas subcadenas de la variable se asignan a las variables b, y en el futuro todos usarán solo ellas: objetos y . Ya nadie accede simplemente a la variable a; no hay referencias a ella (esto es lo que quiere decir el autor del artículo). Como resultado, en algún momento se activa el recolector de basura y (en la forma más general, por supuesto) obtenemos 2 situaciones diferentes: JDK 6 : el objeto se destruye (se recolecta basura) , PERO - la enorme matriz original en el montón está vivo; se utiliza constantemente y . JDK 7: el objeto a se destruye junto con la matriz original en el montón. Este es el punto en JDK 6 que puede provocar una pérdida de memoria. cabcabc

5. subcadena() en JDK 7

El método se ha mejorado en JDK 7. En JDK 7 substring(), en realidad crea una nueva matriz en el montón. Traducción: Creación de objetos de cadena en Java - Uso
//JDK 7
public String(char value[], int offset, int count) {
	//check boundary
	this.value = Arrays.copyOfRange(value, offset, offset + count);
}

public String substring(int beginIndex, int endIndex) {
	//check boundary
	int subLen = endIndex - beginIndex;
	return new String(value, beginIndex, subLen);
}
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION