2015-04-30 20 views
5

Recentemente, sono incappato la seguente sintassi java:Strano sintassi di dichiarazione ArrayList in java

ArrayList<String> nodes = new ArrayList<String>(){{add("n1");add("n2");}}; 

In un primo momento, ho pensato che si tratta di un errore di sintassi, ma con mia sorpresa, il codice non dava compilazione o errore di runtime.

ho le seguenti domande:

  • Esiste una definizione standard e la documentazione per tale dichiarazione in Java?
  • Cosa succede quando questo codice è compilato?

Vi prego di indicarmi la letteratura pertinente.

+0

Grazie per avermi indirizzato verso la domanda di cui sopra. – Bhoot

risposta

2

Questo crea una classe anonima con un costume initializer (vedi inizializzazione grado Utenti):

Normalmente, si dovrebbe mettere il codice per inizializzare una variabile di istanza in un costruttore. Esistono due alternative all'utilizzo di un costruttore per inizializzare le variabili di istanza: blocchi di inizializzazione e metodi finali. blocco di inizializzazione per le variabili di istanza sono proprio come blocco di inizializzazione statico, ma senza la parola chiave static:

{ 
    // whatever code is needed for initialization goes here 
} 

E 'comoda quando si vuole una lista con i membri già in esso, ma produce più codice durante la compilazione perché l'anonimo la classe è in realtà compilata in una classe (globale) diversa che estende ArrayList.

ho letto di recente this post che è rilevante per la questione:

Il primo punto da notare è che il runtime Java ha alcuna comprensione di classi interne a tutti. Indipendentemente dal fatto che la classe interna sia nominata o anonima, viene utilizzata una procedura smoke-and-mirrors per convertire la classe interna in una classe globale. Se la classe ha un nome, il compilatore genera file di classe i cui nomi hanno il formato [outer] $ [inner] - $ è un identificatore legale in Java. Per le classi interne, i file di classe generati sono semplicemente numerati. Quindi, quando l'esempio di Thread all'inizio di questo articolo è compilato, ci ritroviamo con un file di classe chiamato Test $ 1.class. Il numero '1' indica che questa è la prima classe anonima definita all'interno della classe Test.

0

È un blocco esempio, che viene eseguito sulla costruzione, di una sottoclasse anonima.

A meno che non ci sia una buona ragione, non farlo. Preferire:

List<String> nodes = Arrays.asList("n1", "n2"); 

O se avete bisogno mutevolezza:

List<String> nodes = new ArrayList(Arrays.asList("n1", "n2")); 

Poiché la classe anonima mantiene un riferimento all'istanza contenente della classe è dichiarata in, che può portare a perdite di memoria.

+0

Ma tra entrambi i modi c'è una differenza da tenere a mente. La tua strada crea un elenco non modificabile.Se l'elenco non deve essere modificato, la soluzione è quella che dovrebbe essere scelta. – SubOptimal

+0

@subopt leggi modifica :) – Bohemian