Domanda

Purtroppo non ho codificato Java per circa cinque anni e io assolutamente non riesco a ricordare come o perché il seguente codice funziona.

mi sono imbattuto in un esempio simile e rotto verso il basso per questo. L'enfasi è sulla parte sotto il commento: non ho ricevuto la notazione costruttore seguito dal blocco tra doppie parentesi quadre. E, purtroppo, non riesco a trovare nulla nella documentazione Java oppure utilizzando Google (che parola (s) dovrei Google?).

package syntaxtest;

public class Main {

    public static void main(String[] args) {

        // What kind of notation is this?
        MyTest tester = new MyTest() {{
            setName("John Johnson");
        }};

        System.out.println(tester.getName());
    }
}


class MyTest {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Così qui sono le mie domande:

  1. Come è questa notazione / sintassi chiamato?
  2. Dove posso leggere un po 'di documentazione a riguardo?

Credo / spero di essere in grado di risolvere la seconda questione da me se qualcuno mi può fornire con la risposta alla prima domanda.

Per rendere più chiaro: so che l'uscita è John Johnson;) Ma non so il motivo per cui si sta lavorando

.
È stato utile?

Soluzione

Questo è noto come doppia inizializzazione brace :

  

La prima doppietta crea un nuovo   AnonymousInnerClass, la seconda   dichiara un blocco un'istanza di inizializzazione   che viene eseguito quando l'interna anonima   di classe viene creata un'istanza. Questo tipo di   blocco di inizializzazione viene chiamato formalmente   "istanza inizializzatore", perché   è dichiarata nell'ambito dell'istanza   della classe - "inizializzatori statici"   sono un concetto relativo in cui il   static parola chiave è collocato prima del   tutore che avvia il blocco, e che   viene eseguito a livello di classe non appena   come classloader completa loading   la classe (specificato a    http://java.sun.com/docs/books /jls/third_edition/html/classes.html#8.6 )   Il blocco di inizializzazione può utilizzare qualsiasi   metodi, campi e le variabili finali   disponibili nell'ambito contenente, ma   bisogna diffidare del fatto che   inizializzatori vengono eseguiti prima   costruttori.

     

Questo funziona solo solo per i non-finale   classi perché crea un   sottoclasse anonima.

Altri suggerimenti

Diamo layout il codice un po 'diverso:

MyTest tester = new MyTest() {
  {
    setName("John Johnson");
  }
};

Quello che vedete qui è chiamato doppia inizializzazione brace . Hai una sottoclasse interna anonima di classe MyTest, insieme ad un blocco di inizializzazione, che è un blocco che contiene il codice che viene eseguito quando l'oggetto viene costruito.

Normalmente, si dovrebbe mettere tale codice nel costruttore, ma dal momento che le classi interne anonime non possono avere costruttori, questo è l'unico modo per garantire il codice viene eseguito quando si suppone.

Detto questo, è un po 'brutto per fare questo. Ci sono modi migliori. Tuttavia, io uso io stesso a volte, di solito nella seguente forma per creare una mappa immutabile:

final Map<String, Integer> textToInt = Collections.unmodifiableMap(new HashMap<String, Integer>() {{
    put("one", 1);
    put("two", 2);
    // etc
}});

Il che crea una nuova mappa, prevale su di esso, aggiunge alcuni valori ad esso nel blocco di inizializzazione, e lo avvolge in una mappa modificabile.

MyTest tester = new MyTest() {{
   setName("John Johnson");
}};

è lo stesso di

MyTest tester = new MyTest();
tester.setName("John Johnson");
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top