2014-07-24 8 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); 
    } 
} 

Wenn ich diesen Code schrieb ich ausgegeben, um wie folgt erhalten:Erstellen Objekt in Java statische Schlüsselwort

ini 
cons 
stat 
ini 
cons 
0 

Hier, wenn ich ein neues Objekt in main(), class abc erstellt wurde static Variablen und Blöcke geladen und werden ausgeführt, so wie sie geschrieben sind. Wenn die Steuerung in Zeile 4 kam, wird static abc h = new abc(); Instance Initialization Block aufgerufen. Warum? Warum wird ein statischer Block nicht aufgerufen, wenn ein neues Objekt in Zeile 4 erzeugt wird und bis zu diesem Zeitpunkt ein statischer Block auch nicht einmal aufgerufen wurde, so sollte gemäß der Konvention ein statischer Block aufgerufen worden sein. Warum kommt diese unerwartete Ausgabe?

+1

möglich Duplikat von [Java statische Klasseninitialisierung] (http://stackoverflow.com/questions/3499214/java-static-class-initialization) – DavidPostill

+0

Statischer Code wird nur einmal ausgeführt, wenn das zweite Objekt erstellt wird (innerhalb der erster) es wird nicht ausgeführt. Ich bin überrascht, dass 'ini' an dieser Stelle ausgeführt wird. – Eypros

+2

@ DavidPostill - Tagged Post löscht das Konzept, dass statische Initialisierung normalerweise passiert. Aber meine Hauptfrage ist, warum der statische Block nicht in Zeile 4 aufgerufen wird und stattdessen der Instanzinitialisierungsblock aufgerufen wurde. –

Antwort

6

Statische Felder Initialisierung und statische Blöcke werden in der Reihenfolge ausgeführt, in der sie deklariert sind. In Ihrem Fall ist der Code entspricht dies nach Deklaration und Initialisierung Trennung:

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); 
    } 
} 

Also, wenn Sie Linie 4 aus dem Code zu erreichen, wird die statische Initialisierung tatsächlich ausgeführt wird und noch nicht fertig. Daher wird Ihr Konstruktor aufgerufen, bevor stat gedruckt werden kann.

7

JLS says:

Die statischen Initialisierungen und Klasse Variableninitialisierungen sind in Text Reihenfolge, durchgeführt und in der Klasse deklarierten Variablen der Klasse, deren Erklärungen beziehen sich möglicherweise nicht textlich nach dem Gebrauch erscheinen, obwohl Diese Klassenvariablen sind im Geltungsbereich (§8.3.2.3). Diese Einschränkung ist entwickelt, um zu kompilieren, die meisten kreisförmigen oder sonstwie fehlerhafte Initialisierungen zu erkennen.

Welches ist genau dein Fall.

Hier ist Ihre ursprüngliche Beispiel: http://ideone.com/pIevbX - statische Initialisierer von abc geht nach statische Instanz von abc zugeordnet ist - so statische Initialisierer nicht ausgeführt werden kann - es ist textlich nach statischer Variableninitialisierung

bewegen Linie Lassen Sie uns 4 nach statischen Initialisierungsbaustein - 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 

} 

Jetzt können Sie die folgende Ausgabe:

stat 
ini 
cons 
ini 
cons 
0 

Jetzt Initialisierungsreihenfolge ist mehr wie erwartet - erste statische Initialisierer und dann statische Instanz von abc initialisiert gemeinsam Weise genannt.

Verwandte Themen