2009-12-12 18 views
8
class test 
{ 
    test() 
    { 
     System.out.println("Constructor"); 
    } 

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

} 
public class sample 
{ 
    public static void main(String [] a) 
    { 
     test t = new test();   
    } 
} 

nel codice precedente, perché la dichiarazione fornita all'interno delle parentesi graffe ((i.e) "Hai") viene stampata prima dell'esecuzione del costitatore.dubbi nelle nozioni di base di Java?

risposta

31

Lasciate esprimere un più chiaro esempio:

public class Test { 

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

    { 
     System.out.println("instance initializer"); 
    } 

    public Test() { 
     System.out.println("constructor"); 
    } 

} 

e testare come segue:

public class Main { 

    public static void main(String[] args) { 
     Test test1 = new Test(); 
     Test test2 = new Test(); 
    } 

} 

uscita:

static initializer 
instance initializer 
constructor 
instance initializer 
constructor 

Gli inizializzatori statici vengono eseguite solo volta durante il runtime, in particolare durante il caricamento della classe. Gli inizializzatori dell'istanza vengono eseguiti durante ogni istanziazione prima del costruttore.

È possibile avere più di uno di essi e verranno eseguiti nell'ordine così come appaiono nella codifica.

Il vantaggio principale degli inizializzatori di istanza è che vengono eseguiti indipendentemente dal costruttore che si utilizza. Si applicano a ciascuno di essi in modo da non dover duplicare l'inizializzazione comune su tutti loro.

Il vantaggio principale degli inizializzatori statici è che vengono eseguiti una sola volta durante il caricamento di classe. Un esempio del mondo reale ben noto è il driver JDBC. Quando si esegue

Class.forName("com.example.jdbc.Driver"); 

che esegue solo le static inizializzatori, allora qualsiasi (decente) driver JDBC si registrerà nel DriverManager come segue

static { 
     DriverManager.registerDriver(new com.example.jdbc.Driver()); 
} 

questo modo il DriverManager può trovare il driver JDBC destro durante getConnection().

5

Sì. È un instance initializer. Viene eseguito non appena la classe viene istanziata.

+2

Quindi la parola chiave statica è facoltativa? – blackanchorage

+0

quindi se si crea un blocco statico nel codice sopra, che eseguirà prima il blocco statico o il blocco di inizializzatore statico? .... si può spiegare cos'è l'inizializzatore statico? – Hariharbalaji

+1

Non è sicuramente un inizializzatore 'static'. – BalusC

2

Le parentesi graffe immediatamente all'interno di una classe introducono un inizializzatore di istanza (introdotto in Java 1.1). Sono trattati allo stesso modo del codice per assegnare campi scritti come parte della dichiarazione. Così i seguenti sono equivalenti:

private final Thing x = new Thing(); 

e

private final Thing x; 
{ 
    x = new Thing(); 
} 

Il codice viene eseguito da costruttori subito dopo aver chiamato un costruttore eccellente. Quindi, supponendo che nessun altro l'inizializzazione, il codice può essere scritto in modo equivalente come parte del costruttore:

private final Thing x; 
public MyCLass() { 
    super(); // Often implicit. 
    x = new Thing(); 
} 

parentesi graffe nella stessa posizione, preceduto dalle static parole chiave e statiche inizializzatori, eseguito una volta quando una classe è inizializzato, non su una base per istanza.

3

Nel codice precedente perché la dichiarazione fornita all'interno delle parentesi ((i.e) "Hai") viene stampata prima dell'esecuzione del costruttore.

Poiché questo è il comportamento previsto come descritto nella sezione 12.5 Creation of New Class Instances del Java Language Specification :)

Poco prima un riferimento al nuovo oggetto creato viene restituito come risultato , il costruttore si intende trattati per inizializzare il nuovo oggetto utilizzando la seguente procedura:

  1. Assegnare arg umenti per la funzione di costruzione alle variabili del parametro appena creato per questa chiamata del costruttore .
  2. Se questo costruttore inizia con un costruttore invocazione esplicita di un altro costruttore della stessa classe (usando this), quindi valutare le argomentazioni e processo che costruttore invocazione in modo ricorsivo utilizzando questi stessi cinque passi. Se la chiamata del costruttore completa improvvisamente, quindi questa procedura viene completata improvvisamente per lo stesso motivo; In caso contrario, continuare con il passaggio 5.
  3. Questo costruttore non inizia con un esplicito costruttore invocazione di un altro costruttore in stessa classe (utilizzando this). Se questo costruttore è per una classe diversa Object, allora questo costruttore sarà inizia con un esplicito o implicito invocazione di un costruttore della superclasse (usando super). Valutare gli argomenti ed elaborare quella ricorsione della superclasse in modo ricorsivo utilizzando gli stessi cinque passaggi. Se la chiamata del costruttore completa improvvisamente , allora questa procedura completa improvvisamente lo stesso motivo . Altrimenti, continuare con il passo 4.
  4. Eseguire inizializzatori istanza e istanza inizializzatori variabili per questa classe, assegnando i valori di istanza initializers variabili ai corrispondenti variabili di istanza, in nell'ordine da sinistra a destra in cui sono visualizzati testualmente nel codice sorgente per la classe. Se si esegue uno qualsiasi degli , questi inizializzatori provocano un'eccezione , quindi non vengono elaborati ulteriori inizializzatori e questa procedura si completa improvvisamente con la stessa eccezione . Altrimenti, proseguire con il passo 5. (In alcuni primi implementazioni, il compilatore erroneamente omesso il codice per inizializzare un campo se l'espressione inizializzatore campo era una costante un'espressione il cui valore è pari a il valore di inizializzazione predefinito per il suo tipo.)
  5. Esegui il resto del corpo di questo costruttore. Se l'esecuzione viene completata improvvisamente, la procedura completa improvvisamente lo stesso motivo per . In caso contrario, questa procedura viene completata normalmente.

Vedere la sezione 8.6 Instance Initializers per maggiori dettagli su ... esempio inizializzatori.

Problemi correlati