2012-06-23 8 views
5

En Java, aparentemente, se prefiere String s = "foo" sobre String s = new String("foo").¿Por qué no debería instanciar un objeto de cadena con un constructor?

¿Por qué? ¿No se ha creado un nuevo objeto de cadena en ambos casos? ¿Por qué el primer caso impedía llamar a un constructor?

+0

posible duplicado de [¿Cuál es la diferencia entre "texto" y la nueva cadena ("texto") en Java?] (http://stackoverflow.com/questions/3052442/what-is-the-difference-between-text-and-new-stringtext-in-java). (Una vez que comprende la diferencia entre las dos formas, es obvio por qué se prefiere la primera ... en casi todos los casos). –

Respuesta

9

¿Por qué?

ya que el segundo enfoque se traduce en dos objetos de cadena (el original debido a la cadena literal, más una copia explícita).

+0

El segundo enfoque da como resultado dos objetos de cadena, solo cuando "foo" aún no se encuentra en la Cadena. . –

+0

@KazekageGaara, para hacer referencia a '" foo "' ya debe estar en "el grupo". Se declara en el grupo constante de la clase y se coloca allí mientras la clase (o el método concreto) es procesada por JVM – bestsss

1

No creo que sea preferible. Supongo que el único "beneficio" que obtienes es que si utilizas incorrectamente el operador "==" en lugar del método equals, tendrás dos instancias diferentes de una cadena que fallarán más rápido, lo que te pedirá que corrijas tu código. (El operador == puede "éxito" y fallar de forma impredecible)

A menos que, por supuesto, su código requiere a construir dos instancias diferentes por cualquier razón

+0

. Requiere dos instancias diferentes de un 'String' (con contenido idéntico) suena casi tan bueno como requerir dos "instancias" de un "int" ... tal vez hay algún mapa de identidad maltratado en alguna parte ... pero espero que no: -/ –

+0

Sí, dado que String es inmutable, no puedo pensar en ninguna razón por la cual cualquiera requeriría tal cosa.Es por eso que dije "por cualquier motivo" –

4

El primer caso es una cadena literal , simplemente una taquigrafía, el idioma te ofrece crear una cadena. El constructor de la clase String aún recibe llamadas, solo que no explícitamente, lo que significa menos tipeo y menos desorden de código.

El segundo caso toma el objeto String ya creado por el literal y lo pasa a un constructor, que copia el contenido para crear un nuevo objeto String por separado. El literal seguirá existiendo porque los literales están internados.

Raramente hay un punto para usar el constructor String (más o menos cuando ha creado una subcadena de una cadena muy grande y desea liberar la memoria utilizada por el resto de la cadena, porque las subcadenas usan de manera predeterminada misma matriz subyacente carbón como la cadena original, sólo con un desplazamiento de longitud y diferente.

+0

punto pequeño: * El literal seguirá existiendo porque los literales están internados. *, Si el literal no tiene referencias entrantes (como estar en un grupo constante de clase) es libre de ser GC 'd, liberando efectivamente la perm-gen (siempre que la JVM use perm-gen, otros no) – bestsss

+0

@bestsss: ¿Pero los literales no siempre son parte del grupo constante? –

+1

El grupo constante es parte de su clase. Cadena declarada fuera del conjunto constante vaya al perm-gen (bajo Suns JVM, algunas JVM no usan perm-gen). Pero después de que el cargador de clases class + es GC'd, la JVM es libre de "liberar" la instancia interna también. De lo contrario, todos los nombres de clase, literales, etc. se filtrarán después de "anular la implementación"/"volver a desplegar" – bestsss

1

¿por qué? ¿no es una nueva cadena objeto creado en ambos casos?

no, el forma inicial siendo un cadena literal será internado de tal manera que sólo se crea una instancia:

String s = "foo"; 
String s2 = "foo"; 

s == s2 => true

Cuestiones relacionadas