2010-12-08 20 views
5

J'ai récemment trouvé ce qui me semble être une nouvelle syntaxe pour initialiser statiquement une ArrayList:
new ArrayList() {{ add("first"); add("second"); }};
Qu'est-ce que la {{syntaxe sur initialiseur ArrayList vraiment faire

Ma question est, ce qui se passe réellement Là? Est-ce un raccourci pour définir un bloc statique (je pensais qu'il aurait besoin du mot-clé static)? Ou juste un moyen de définir un constructeur par défaut? Autre chose? Quelle version de Java est-elle devenue valide?

Une explication plus un lien à la lecture plus serait grandement apprécié.

éditer: Ma classe de test pour montrer si le bloc d'initialisation s'exécute avant ou après que le constructeur soit en dessous. Les résultats montrent que les blocs de initialiseur exécutent avant que l'autre code constructeur:

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(); 
    } 
} 

Sortie:

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

Où avez-vous trouvé cette nouvelle syntaxe? Avez-vous un lien vers un article ou quelque chose à partager? – romacafe

+0

BTW: pour ajouter à la confusion, vous pouvez avoir n'importe quel nombre de blocs statiques {} et {} n'importe où dans votre classe (en dehors des définitions de méthodes bien sûr) –

+0

Related: http://stackoverflow.com/questions/924285/efficience- of-java-double-brace-initialisation C'est d'ailleurs pas nouveau. A déjà été en Java depuis des lustres. C'est en effet très rarement utilisé, et avec une bonne raison. – BalusC

Répondre

6

Vous créez une nouvelle sous-classe anonyme de ArrayList, avec un initialiseur instance qui appelle add() deux fois.

Il est le même 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(); 

Notez que, personnellement, je ne conseille pas comme un idiome, car elle conduira à une explosion de classe fichier.

+0

Est-ce que quelqu'un voudrait commenter si l'initialiseur est invoqué avant ou après l'invocation de super()? –

+0

Il devrait être après super() comme toujours appelé en premier. –

+0

Merci pour la réponse rapide. En ce qui concerne l'avant/après, j'ai construit une classe de test rapide, et il exécute le bloc d'initialisation avant. – Gus

4

Il est un bloc d'initialisation pour les variables d'instance.

De la documentation Oracle:

blocs Initializer par exemple les variables ressemblent statiques blocs initialiseur, mais sans mot-clé statique:

{ 

    // whatever code is needed for initialization goes here 
} 

Les copies du compilateur Java initialiser blocs dans chaque constructeur. Par conséquent, cette approche peut être utilisée pour partager un bloc de code entre plusieurs constructeurs.

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

3

Lorsque vous écrivez new ArrayList() { } vous créez une sous-classe anonyme de ArrayList. Le { } comme dans les crochets les plus internes dans votre code dénote un bloc d'initialisation et est effectivement copié dans chaque constructeur.

EDIT: Vous avez réponse vous vite!