2012-05-20 16 views
6
class A { 

String s4 = "abc"; 

static public void main(String[]args) { 

     String s1 = "abc"; 
     String s2 = "abc"; 
     String s3 = new String("abc"); 
     A o = new A(); 
     String s5 = new String("def"); 

     System.out.println("s1==s2 : " + (s1==s2)); 
     System.out.println("s1==s1.intern : " + (s1==s1.intern())); 
     System.out.println("s1==s3 : " + (s1==s3)); 
     System.out.println("s1.intern==s3.intern : " + (s1.intern()==s3.intern())); 
     System.out.println("s1==s4 : " + (s1==o.s4)); 
} 
} 

La salida:Java: literal cadenas

s1==s2 : true 
s1==s1.intern : true 
s1==s3 : false 
s1.intern==s3.intern : true 
s1==s4 : true 

Mis preguntas:

1. ¿Qué sucede por "String s1 = "abc"? Supongo que el objeto String se agrega al grupo en la clase String como una cadena interna? ¿Dónde se coloca? La "generación permanente" o solo el montón (como el miembro de datos de la instancia de la clase String)?

2.¿Qué ocurre con "String s2 = "abc"? Supongo que no se crea ningún objeto. Pero, ¿significa esto que Java Intepreter necesita buscar todas las cadenas internas? ¿Esto causará algún problema de rendimiento?

3.Seems String s3 = new String("abc") no utiliza cadenas internas.¿Por qué?

4.Will String s5 = new String("def") ¿creará alguna nueva cuerda internificada?

Respuesta

3

1. ¿Qué ocurre para "String s1 = 'abc'?

En tiempo de compilación una representación de lo literal se escribe en la 'parte del grupo de constantes' del archivo de clase de la clase que contiene este código

Cuando se carga la clase, se lee la representación del literal de cadena en el grupo de constante del archivo de clase, y se crea un nuevo objeto String a partir de él. Esta cadena se intercala y la referencia a la cadena interna se "incrusta" en el código.

En tiempo de ejecución, la referencia a la Cadena previamente creada/interna se asigna a s1. (No se realiza creación de cadena o interna cuando se ejecuta esta instrucción.)

Supongo que el objeto String se agrega al grupo en la clase String como cadena interna?

Sí. Pero no cuando el código se ejecuta.

¿Dónde está colocado? La "generación permanente" o solo el montón (como el miembro de datos de la instancia de la clase String)?

Se almacena en la región permgen del montón. (La clase String no tiene campos estáticos. El grupo de cadena de JVM se implementa en código nativo.)

2. ¿Qué ocurre para "String s2 = "abc"?

Nada sucede en tiempo de carga Cuando el compilador creó el archivo de clase, reutilizó la misma entrada de grupo de constantes para el literal que se usó para el primer uso del literal. Por lo tanto, la referencia de cadena utilizada por esta instrucción es la misma que la utilizada en la declaración anterior.

Supongo que no se ha creado ningún objeto.

Correcto.

¿Pero significa esto que Java Intepreter necesita buscar todas las cadenas internas? ¿Esto causará algún problema de rendimiento?

No, y no. El intérprete de Java (o código compilado JIT) utiliza la misma referencia que se creó/incrustó para la instrucción anterior.

3.Seems String s3 = new String ("abc") no utiliza string interno.¿Por qué?

Es más complicado que eso. La llamada de constructor usa la cadena interna, y luego crea una nueva Cadena, y copia los caracteres de la cadena interna a la nueva representación de Cadena. La cadena recién creada se asigna al s3.

¿Por qué? Porque new es especificado como siempre creando un nuevo objeto (vea JLS), y el constructor String es especificado como copiando los caracteres.

4.Will String s5 = new String ("def") crea una nueva secuencia interna?

una nueva cadena de internación se crea en tiempo de carga (para "def"), y luego un nuevo objeto String se crea en tiempo de ejecución que es un copia de la cadena de internación. (Consulte el texto anterior para obtener más detalles.)

+0

Gracias amigo. Su respuesta se ve genial. Una pregunta más: si el literal se escribe en la parte "constante del grupo" del archivo de clase, ¿cómo es que 2 literales (el mismo contenido) en 2 clases usan la misma cadena interna? –

+0

@DonLi - el grupo de constantes es una sección de un archivo de clase. La especificación del archivo de clase no permite que un archivo de clase haga referencia al conjunto constante de otro archivo de clase. –

-1

String s1 = "abc"; crea un nuevo String y lo interna.

String s2 = "abc"; arrastrará el mismo objeto utilizado para s1 desde el grupo interno. La JVM hace esto para aumentar el rendimiento. Es más rápido que crear un nuevo String.

Llamar a new String() es redundante ya que devolverá un nuevo Objeto de Cadena implícito. No recupérela del grupo interno.

Como dice Keyser, == compara las cadenas para la igualdad de objetos, devolviendo verdadero si son el mismo objeto. Al comparar el contenido de cadena que debe utilizar .equals()

+0

¿Qué parte he dicho incorrectamente? – Jivings

+0

Para 1 crea una nueva Cadena en tiempo de compilación. Párrafo 2: la JVM no tiene nada que ver con eso. – EJP

+0

Bajé la votación antes de que editaras (y cerraste) tu respuesta, cuando dijiste que "abc" y nueva Cadena ("abc") eran las mismas cosas. –

5
  1. El compilador crea un objeto de cadena "ABC" en la piscina constante, y genera una referencia a él en el código de bytes para la instrucción de asignación.

  2. See (1). Sin búsqueda; no hay problema de rendimiento

  3. Esto crea un nuevo objeto String en el tiempo de ejecución, porque eso es lo que hace el operador 'nuevo': crear nuevos objetos.

  4. Sí, para "def", pero debido a (3) también se crea un nuevo String en el tiempo de ejecución.

Los objetos String en 3-4 no están internados.

+1

El compilador crea un literal String en el conjunto constante. Pero eso se resuelve en una referencia cuando se carga la clase. – Jivings

+0

Esta respuesta todavía está mal. – Jivings

+0

@Jivings ¿Es incorrecto cómo? Comentarios como ese no sirven para nadie. – EJP

2

Ver this answer on SO. También vea this artículo de la wikipedia sobre el Interinato de Cuerdas.