2009-09-03 16 views

risposta

62

Si chiama double curly brace initialization. (EDIT: Link rimosso, archived here)

Significa che si sta creando una sottoclasse anonima e il codice all'interno delle doppie parentesi è fondamentalmente un costruttore. È spesso usato per aggiungere contenuti alle raccolte perché la sintassi di Java per la creazione di quelle che sono essenzialmente costanti di raccolta è alquanto scomoda.

Così si potrebbe fare:

List<String> list = new ArrayList<String>() {{ 
    add("one"); 
    add("two"); 
    add("three"); 
}}; 

invece di:

List<String> list = new ArrayList<String>(); 
list.add("one"); 
list.add("two"); 
list.add("three"); 

Io in realtà non mi piace che e preferiscono fare questo:

List<String> list = Arrays.asList("one", "two", "three"); 

Così doesn' In questo caso ha molto senso mentre per, diciamo, Maps, che non ha un aiuto conveniente.

+0

@skaffman È molto utile in "fluid java" come [JATL] (http://code.google.com/p/jatl) tentativi. –

+6

Si noti che Arrays.asList() restituisce java.util.Arrays.ArrayList.ArrayList e non java.util.ArrayList, che ha funzionalità limitate. – Asaf

+3

Questa tecnica è complicata e presenta alcuni avvertimenti. È possibile concludere con il contratto equals() interrotto o un maggiore utilizzo della memoria senza una buona ragione. È meglio evitare l'inizializzazione della doppia parentesi se non si sa esattamente cosa si sta facendo. Guarda [questo] (http://www.ayp-sd.blogspot.com/2012/12/double-brace-initialization-in-java.html) post per maggiori dettagli. –

11

Le parentesi "esterne" indicano che si sta creando una sottoclasse anonima, le seconde sono l'inizializzatore dell'oggetto. L'inizializzatore viene eseguito prima del costruttore della classe, ma dopo qualsiasi chiamata super (e quindi anche dopo eventuali inizializzatori della superclasse). È possibile utilizzare gli inizializzatori anche in classi non anonime, che è un modo conveniente per iniziare i campi final se si hanno diversi costruttori che non possono chiamarsi reciprocamente, o campi che richiedono un'inizializzazione più complessa di quanto consentano gli usuali inizializzatori di campo.

Considerate questa classe:

class X extends Y{ 
    private final int lulz; 

    private static boolean someCondition(){...} 
    private static boolean danger() throws SomeException { ... } 
    public X(A a) throws SomeException { 
     super(a); 
     lulz = someCondition()? danger() : 0; 
    } 
    public X(B b) throws SomeException { 
     super(b); 
     lulz = someCondition()? danger() : 0; 
    } 
} 

Potrebbe essere riscritta come:

class X extends Y{ 
    private final int lulz; 

    private static boolean someCondition(){...} 
    private static boolean danger() throws SomeException { ... } 
    { // initalizer -- might throw SomeException! 
     lulz = someCondition()? danger() : 0; 
    } 
    public X(A a) throws SomeException { super(a); } 
    public X(B b) throws SomeException { super(b); } 
} 

Se l'inizializzatore può lanciare un'eccezione controllata, tutti i costruttori devono dichiarare possono buttare.

4

Si sta creando un anonymous class e utilizzando il class Instance initialize r linguaggio, in questo modo:

class X { 
    private Y var1; 

    private X() { 
     Z context = new Z(
       new SystemThreadPool()) { 
        {      // This is the initialize idiom 
         var1 = new Y();  // 
        }      // 
       } 
     ); // BTW you are missing ")" 
    } 
} 
1

Come accennato nelle risposte precedenti, doppia parentesi graffa di inizializzazione è corretta.

Utilizza una tecnica specifica per Inizializzazione dei membri di istanza in Java. È un modo sintetico per definire in una definizione di classe, un blocco di codice condiviso che verrà eseguito quando viene attivato uno qualsiasi dei costruttori di classi.

Aggiungo il collegamento allo official Java documentations descrivendolo per una vista più ampia sull'argomento.

Dal documentation:

blocco di inizializzazione per le variabili di istanza guardare proprio come statici blocco di inizializzazione, ma senza la parola chiave static:

{

// whatever code is needed for initialization goes here 

}

Il compilatore Java copia i blocchi inizializzatore int o ogni costruttore. Pertanto, questo approccio può essere utilizzato per condividere un blocco di codice tra più costruttori .

Problemi correlati