2014-07-24 10 views
14
class abc { 
    int a = 0; 
    static int b; 
    static abc h = new abc(); //line 4 

    public abc() { 
     System.out.println("cons"); 
    } 

    { 
     System.out.println("ini"); 
    } 

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

public class ques { 
    public static void main(String[] args) { 
     System.out.println(new abc().a); 
    } 
} 

quando ho scritto questo codice sto ottenendo in uscita in ordine come questo:Creazione oggetto utilizzando parola chiave static in Java

ini 
cons 
stat 
ini 
cons 
0 

qui quando ho creato un nuovo oggetto in main(), class abc ma ho caricato e static variabili e blocchi vengono eseguiti nell'ordine in cui sono scritti. Quando il controllo è arrivato alla riga 4 static abc h = new abc(); viene chiamato il blocco di inizializzazione dell'istanza. Perché? perché il blocco statico non viene chiamato quando viene creato un nuovo oggetto alla riga 4 e fino a quel momento il blocco statico non è stato chiamato neanche una volta, quindi in base al blocco statico della convenzione avrebbe dovuto essere chiamato. Perché viene questa uscita inaspettata?

+1

possibile duplicato del [Java inizializzazione classe statica] (http://stackoverflow.com/questions/3499214/java-static-class-initialization) – DavidPostill

+0

statica del codice viene eseguito solo quindi una volta quando viene creato il secondo oggetto (all'interno della il primo) non viene eseguito. Sono sorpreso che "ini" sia eseguito a questo punto però. – Eypros

+2

@ DavidPostill- Il post con tag elimina il concetto di come avviene normalmente l'inizializzazione statica. Ma il mio problema principale è che il blocco statico non viene chiamato alla riga 4 e invece è stato chiamato il blocco di inizializzazione dell'istanza. –

risposta

6

Inizializzazione campi statici e blocchi statici vengono eseguiti nell'ordine in cui sono dichiarati. Nel tuo caso, il codice è equivalente a questa dichiarazione dopo la separazione e l'inizializzazione:

class abc{ 
    int a; 
    static int b; 
    static abc h;//line 4 

    static { 
     h = new abc();//line 4 (split) 
     System.out.println("stat"); 
    } 

    public abc() { 
     a = 0; 
     System.out.println("ini"); 
     System.out.println("cons"); 
    } 
} 

public class ques{ 
    public static void main(String[] args) { 
     System.out.println(new abc().a); 
    } 
} 

Quindi, quando si raggiunge la linea 4 dal codice, l'inizializzazione statica è effettivamente in esecuzione e non ancora finito. Quindi il tuo costruttore viene chiamato prima che stat possa essere stampato.

7

JLS says:

Gli inizializzatori statici e classe inizializzatori variabili vengono eseguiti in ordine testuale, e non possono riferirsi a variabili di classe dichiarate nella classe cui dichiarazioni comparire testualmente dopo l'uso, anche se queste variabili di classe sono nel campo di applicazione (§8.3.2.3). Questa restrizione è progettata per rilevare, al momento della compilazione, la maggior parte delle inizializzazioni in forma irregolare o circolare .

Qual è esattamente il tuo caso.

Ecco il vostro esempio originale: http://ideone.com/pIevbX - inizializzatore statico di abc va dopo viene assegnato un'istanza statica di abc - inizializzazione in modo statico non può essere eseguito - è testualmente dopo statica inizializzazione delle variabili

mossa di Let linea 4 dopo blocco di inizializzazione statica - http://ideone.com/Em7nC1:

class abc{ 
int a = 0; 
static int b; 
public abc() { 
    System.out.println("cons"); 
} 
{ 
    System.out.println("ini"); 
} 
static { 
    System.out.println("stat"); 
} 
static abc h = new abc();//former line 4 

} 

Ora è possibile vedere il seguente output:

stat 
ini 
cons 
ini 
cons 
0 

ordina ora l'inizializzazione è più come vi aspettavate - prima chiamato inizializzatore statico e quindi un'istanza statica di abc viene inizializzato in maniera comune.

Problemi correlati