2012-07-20 9 views
16
public class Test { 

    private static final String str1 = new String("en"); 
    private static Test instance = initInstance(); 

    private static final String str2 = new String("en"); 
    private static final String str3 = "en"; 

    private Test() { 
    } 

    public static void main(String[] args) { 
    } 

    private static Test initInstance() { 
     instance = new Test(); 
     System.out.println(str1 + ',' + str2 + ',' + str3); 
     return instance; 
    } 
} 

Teóricamente con la estática de todo el mundo debería dar lugar a "en, en, en".Java - extraño comportamiento estático String - nueva cadena ("XXX") vs "xxx"

Resultado: "es, nula, en"

esperado: "es, null, null" (desde que descubrí el fin estática realmente importa)

alguien puede explicar esto? ¿Qué tan diferente es "en" y el nuevo String ("en")?

+0

+1 porque no tenía idea de que podría inicializar en línea así ... – Izkata

Respuesta

19

Sí. En el momento de invocar el método, str2 aún no se ha inicializado (los campos se inicializan en orden de declaración) y str3 es una constante en tiempo de compilación.

Las constantes de tiempo de compilación están indicadas por el compilador en el archivo de clase. new String ("..") no es una constante, porque usa un constructor.

Las constantes de cadena se definen mediante el literal de cadena: "", y se colocan en un grupo de cadenas en la instancia de jvm para que se reutilicen. Contrariamente a eso, el uso de una nueva Cadena (...) crea una nueva instancia, por lo que debe evitarse.

+5

¿Debe 'inlined' cambiarse a' internalizado'? – corsiKa

11

Esto sucede porque las variables de clase inicializa con constantes se inicializan primero, y sólo entonces son inicializadores más complejos (como sus expresiones usando new String()) hecho (los que entonces se hacen en orden de aparición). Ver JLS §8.3.2.1:

8.3.2.1. Inicializadores de variables de clase

[...]

En tiempo de ejecución, static campos que son final y que se inicializan con expresiones constantes (§15.28) se inicializa por primera vez (§12.4.2). Esto también se aplica a tales campos en las interfaces (§9.3.1). Estos campos son "constantes" que nunca se observará que tengan sus valores iniciales predeterminados (§4.12.5), incluso mediante programas desviados (§13.4.9).

4

1. Su porque str3 = "en" is a String literal in literal pool, and str1 = new String("en") is a String object en la piscina objeto String.

2. Como "en" es un literal, es decir, "constante", se inicializa al comienzo.

3. Su también llamado como doblado de constantes, el cálculo previo de las constantes para ejecutar más rápido.

Cuestiones relacionadas