2010-12-08 23 views
5

recientemente he encontrado lo que me parece ser una nueva sintaxis para inicializar estáticamente un ArrayList:
new ArrayList() {{ add("first"); add("second"); }};
¿Qué significa la {{sintaxis de inicializador ArrayList realmente hacer

Mi pregunta es, lo que realmente está sucediendo ¿ahí? ¿Es ese un atajo para definir un bloque estático (pensé que necesitaría la palabra clave static)? ¿O solo una forma de definir un constructor predeterminado? ¿Algo más? ¿Qué versión de Java hizo esto válido?

Una explicación más un enlace para seguir leyendo sería muy apreciada.

editar: Mi clase de prueba para mostrar si el bloque de inicializador se ejecuta antes o después de que el constructor esté debajo. Los resultados muestran que los bloques de inicializador ejecutan antes que el otro código de constructor:

import org.junit.Test; 

public class InitializerBlockTest { 
    class InitializerTest { 
     { 
     System.out.println("Running initalizer block"); 
     } 

     public InitializerTest() { 
      System.out.println("Running default constructor"); 
     } 
    } 

    class SubClass extends InitializerTest { 
     { 
     System.out.println("Running subclass Initializer block"); 
     } 

     public SubClass() { 
     System.out.println("Running subclass constructor"); 
     } 
    } 

    @Test 
    public void testIt() { 
     new SubClass(); 
    } 
} 

Salida:

Running initalizer block 
Running default constructor 
Running subclass Initializer block 
Running subclass constructor 
+0

¿Dónde encontraste esta nueva sintaxis? ¿Tiene un enlace a un artículo o algo para compartir? – romacafe

+0

BTW: para aumentar la confusión, puede tener cualquier cantidad de bloques estáticos {} y {} en cualquier parte de su clase (fuera de las definiciones de métodos, por supuesto) –

+0

Relacionados: http://stackoverflow.com/questions/924285/efficiency- of-java-double-brace-initialization Por cierto, no es nuevo. Ya ha estado en Java por años. De hecho, es muy poco utilizado, y con una buena razón. – BalusC

Respuesta

6

Usted está creando una nueva subclase anónima de ArrayList, con un inicializador de instancia que exige agregar() dos veces.

Es la misma que:

class MyList extends ArrayList 
{ 

{ // This is an instance initializer; the code is invoked before the constructor. 
add("first"); 
add("second"); 
} 

public MyList() { 
    super(); 
    // I believe initializers run here, but I have never specifically tested this 
    } 
} 

...

List list=new MyList(); 

Tenga en cuenta que, personalmente, no lo aconsejo como una expresión idiomática, ya que dará lugar a la explosión de la clase-archivo.

+0

¿Alguien querría comentar si el inicializador se invoca antes o después de la invocación super()? –

+0

Tendría que estar después de super() como siempre se llama primero. –

+0

Gracias por la respuesta rápida. Con respecto al antes/después, construí una clase de prueba rápida, y ejecuta el bloque de inicialización antes. – Gus

4

Es un bloque de inicialización para variables de instancia.

De la documentación de Oracle:

inicializador bloques, por ejemplo variables que se parecen a bloques inicializador estático, pero sin la palabra clave static:

{ 

    // whatever code is needed for initialization goes here 
} 

Las copias del compilador Java inicializador bloques en cada constructor. Por lo tanto, este enfoque se puede usar para compartir un bloque de código entre constructores múltiples.

Ver: http://download.oracle.com/javase/tutorial/java/javaOO/initial.html

3

Cuando se escribe new ArrayList() { } va a crear una subclase anónima de ArrayList. El { } como en los corchetes más internos de su código denota un bloque de inicializador y en realidad se copia en cada constructor.

EDIT: ¡Seguro que responden rápido!

Cuestiones relacionadas