Uso del constructor String (String) en Java

He leído en artículos y libros que el uso de String s = new String("..."); debe evitarse casi todo el tiempo. Entiendo por qué es así, pero ¿hay algún uso para usar el constructor String (String)? No creo que exista, y no veo ninguna evidencia de lo contrario, pero me pregunto si alguien en la comunidad SO sabe de un uso.


Exact Duplicate: ¿Cuál es el propósito de la expresión new string en java?

Este es un buen artículo: ¡El constructor de cadenas considerado inútil resulta ser útil después de todo!

Resulta que este constructor puede ser útil en al menos una circunstancia. Si alguna vez has echado un vistazo al código fuente String, habrás visto que no solo tiene campos para el valor de matriz char y el recuento de caracteres, sino también para el desplazamiento al comienzo de la cadena. Esto es para que Strings pueda compartir el valor de la matriz char con otras cadenas, por lo general como resultado de llamar a uno de los métodos substring (). Java fue castigado por esto en jwz ‘Java despotrica desde hace años:

La única razón de esta sobrecarga es que String.substring () puede devolver cadenas que comparten la misma matriz de valores. Hacer esto a costa de agregar 8 bytes a cada objeto String no es un ahorro neto …

Ahorro de bytes a un lado, si tiene algún código como este:

 // imagine a multi-megabyte string here String s = "0123456789012345678901234567890123456789"; String s2 = s.substring(0, 1); s = null; 

Ahora tendrá un String s2 que, aunque parece ser una cadena de un solo carácter, contiene una referencia a la gigantesca matriz de caracteres creada en String s. Esto significa que la matriz no será recogida de basura, ¡incluso si anulamos explícitamente los String!

La solución para esto es usar nuestro constructor de cadenas “inútil” antes mencionado de esta manera:

 String s2 = new String(s.substring(0, 1)); 

No es bien sabido que este constructor en realidad copia esos contenidos antiguos en una nueva matriz si la matriz anterior es más grande que el recuento de caracteres en la cadena. Esto significa que los viejos contenidos de String serán recolectados como basura. Feliz feliz alegría Alegría.

Finalmente, Kat Marsen hace estos puntos,

En primer lugar, las constantes de cadena nunca son basura. En segundo lugar, las constantes de cadena están intern’d, lo que significa que se comparten en toda la máquina virtual. Esto ahorra memoria. Pero no es siempre lo que deseas.

El constructor de copias en String le permite crear una instancia de String privada a partir de un literal String. Esto puede ser muy valioso para construir objetos mutex significativos (a efectos de sincronización).

Si mal no recuerdo, el único caso ‘útil’ es donde la cadena original es parte de una matriz de respaldo mucho más grande. (Por ejemplo, creado como una subcadena). Si solo desea mantener la subcadena pequeña y la basura recolectar el búfer grande, podría tener sentido crear un nuevo String.

Solo para ampliar la respuesta de Douglas *, puedo dar un ejemplo firme de dónde lo he usado. Considere leer un archivo de diccionario, con miles de líneas, cada una de ellas una sola palabra. La forma más simple de leer esto es usar BufferedReader.readLine() .

Desafortunadamente, readLine() asigna un búfer de 80 caracteres de forma predeterminada como la longitud de línea esperada. Esto significa que generalmente puede evitar copiar sin sentido, y un poco de memoria desperdiciada no suele ser tan mala. Sin embargo, si carga un diccionario de palabras cortas durante la aplicación, terminará desperdiciando mucha memoria. Mi “pequeña aplicación” absorbió mucha más memoria de la que debería haber hecho.

La solución fue cambiar esto:

 String word = reader.readLine(); 

dentro de esto:

 String word = new String(reader.readLine()); 

… con un comentario, por supuesto!

* No puedo recordar si estaba trabajando con Douglas cuando esto realmente surgió, o si es coincidencia que él respondió esta pregunta en particular.

El constructor es en gran medida redundante y no se recomienda para fines generales. El constructor String con el argumento String raramente se usa excepto para crear una copia independiente de una variable de cadena existente. Básicamente úsela para “aclarar” su código. Nada menos.

de javadoc

 /** * Initializes a newly created {@code String} object so that it represents * the same sequence of characters as the argument; in other words, the * newly created string is a copy of the argument string. Unless an * explicit copy of {@code original} is needed, use of this constructor is * unnecessary since Strings are immutable. * * @param original * A {@code String} */ public String(String original){.....} 

Lo usa si necesita una copia de la Cadena original si no quiere darle un manejo a su cadena original. Pero como las cadenas son inmutables, no veo un caso de uso para esto 😉