Chiamare un metodo Java senza nome


101

Sto guardando il codice qui sotto e ho trovato qualcosa di un po 'strano:

public class Sequence {
    Sequence() {
        System.out.print("c ");
    }

    {
        System.out.print("y ");
    }

    public static void main(String[] args) {
        new Sequence().go();
    }

    void go() {
        System.out.print("g ");
    }

    static {
        System.out.print("x ");
    }
}

Mi sarei aspettato che questo fornisse un errore di compilazione poiché System.outcon "y" non appartiene a una dichiarazione di metodo solo a { }. Perché è valido? Non vedo come dovrebbe o dovrebbe essere chiamato questo codice.

Quando viene eseguito, produce x y c ganche, perché static { }viene chiamato prima del costruttore della sequenza?

Risposte:


149

Questo:

static {
        System.out.print("x ");
    }

è un blocco di inizializzazione statico e viene chiamato quando la classe viene caricata. Puoi averne quanti ne vuoi nella tua classe e verranno eseguiti in ordine di apparizione (dall'alto verso il basso).

Questo:

    {
        System.out.print("y ");
    }

è un blocco di inizializzazione e il codice viene copiato all'inizio di ogni costruttore della classe. Quindi, se hai molti costruttori della tua classe, e tutti devono fare qualcosa di comune all'inizio, devi solo scrivere il codice una volta e metterlo in un blocco di inizializzazione come questo.

Quindi il tuo output ha perfettamente senso.

Come ha commentato Stanley di seguito, vedere la sezione nel tutorial Oracle che descrive i blocchi di inizializzazione per ulteriori informazioni.


12
Bella risposta. Scopri di più sul blocco di inizializzazione su http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
Stanley

6
the code is copied into the beginning of each constructor of the class- questo non è corretto. Supponiamo che il costruttore inizi con super("x ");, il super costruttore verrà eseguito prima di qualsiasi blocco di inizializzazione.
RokL

3
sì, le chiamate implicite ed esplicite al superconstructor verranno eseguite per prime, poi il blocco di inizializzazione e poi il resto del codice del costruttore.
jlordo

25

Non è un metodo ma un blocco di inizializzazione .

 {
    System.out.print("y ");
 }

Verrà eseguito prima della chiamata al costruttore. Mentre

static {
        System.out.print("x ");
       }

è un blocco di inizializzazione statico che viene eseguito quando la classe viene caricata dal caricatore di classi.

Quindi, quando si esegue il codice
1. La classe viene caricata dal caricatore di classi, quindi viene eseguito il blocco di inizializzazione statico
Output: x viene stampato
2. L'oggetto viene creato in modo che venga eseguito il blocco di inizializzazione e quindi il constuctor viene chiamato
Output: y viene stampato seguito da c
3. Viene invocato il metodo principale che a sua volta richiama il metodo go.
Output: g viene stampato

Output finale: xycg
Questo potrebbe aiutare http://blog.sanaulla.info/2008/06/30/initialization-blocks-in-java/


@ Cthulhu: grazie. Era valido fino alla scorsa settimana l'ho aggiornato con un nuovo link.
xyz

16

Questo è un blocco di inizializzazione dell'istanza seguito da un blocco di inizializzazione statico .

{
    System.out.print("y ");
}

viene chiamato quando crei un'istanza della classe.

static {
    System.out.print("x ");
}

viene chiamato quando la classe viene caricata dal programma di caricamento classi. Quindi quando lo fai

new Sequence().go();

la classe viene caricata, quindi viene eseguita static {}, quindi esegue il blocco di inizializzazione dell'istanza, quindi {}viene chiamato il corpo del costruttore e quindi il metodo sull'istanza appena creata. Ergo l'uscita x y c g.


15
static {
        System.out.print("x ");
    }

È un blocco statico e viene chiamato durante il caricamento della classe

{
    System.out.print("y ");
}

È un blocco di inizializzazione

È possibile avere più blocchi di inizializzazione in una classe, nel qual caso vengono eseguiti nella sequenza in cui appaiono nella classe.

Si noti che qualsiasi blocco di inizializzazione presente nella classe viene eseguito prima del costruttore.


10
static {
      System.out.print("x ");
}

è un blocco di inizializzazione condiviso dalla classe (come indicato da static), che viene eseguito per primo.

{
        System.out.print("y ");

}

è un blocco di inizializzazione condiviso da tutti gli oggetti (costruttori) della classe, che viene dopo.

Sequence() {
        System.out.print("c ");
}

è un particolare costruttore per la classe, che viene eseguito per terzo. Il blocco di inizializzazione dell'istanza viene richiamato per primo ogni volta che viene eseguito il costruttore. Ecco perché "y" viene appena prima di "c".

void go() {
        System.out.print("g ");
}

è solo un metodo di istanza associato agli oggetti costruiti utilizzando il costruttore precedente, che è l'ultimo.


9
{
    System.out.print("y ");
}

Questi tipi di blocchi vengono chiamati initializer block. Viene eseguito ogni volta che crei un'istanza di un file class. In fase di compilazione, questo codice viene spostato in ogni costruttore della classe.

Dove come in caso di static initializerblocco: -

static {
    System.out.println("x ");
}

viene eseguito una volta quando la classe viene caricata. Generalmente usiamo il staticblocco inizializzatore quando l'inizializzazione di un staticcampo richiede più passaggi.


6

Viene utilizzato come blocco di inizializzazione e viene eseguito dopo qualsiasi dichiarazione statica . Potrebbe essere utilizzato per garantire che nessun altro possa creare un'istanza della classe (nello stesso modo in cui useresti un costruttore privato) come con il modello di progettazione Singleton .


3
static {
    System.out.print("x ");
}

Static blocksvengono eseguiti solo una volta quando la classe viene caricata e inizializzata da JRE.

E il non-staticblocco verrà chiamato ogni volta che crei una nuova istanza e verrà chiamato appena prima del Constructor.

Poiché qui hai creato solo 1 istanza di Sequencecosì costruito è stata chiamata dopo i non-staticblocchi e quindi il metodo che effettivamente è il tuo obiettivo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.