2013-06-08 16 views
20

Nur frage mich, über den Grund der Erstellung Code wie folgt:Was ist der Unterschied zwischen einem Instanzinitialisierer und einem Konstruktor?

class MyClass extends AnotherClass { 
    { 
    MySecondClass object = new MySecondClass(); 
    object.doSomething(); 
    } 
} 

Was ist der Unterschied zwischen diesem Code und Code in Konstruktor? Dieser Code führt vor die Objekterstellung aus.

+0

Ich habe mich schon eine Weile darüber gewundert, ich erinnere mich, dass ich das vor einer Weile gesehen habe ... weiß jemand, wie diese Struktur heißt? – SimonT

+1

Es wird ein "Initialisierungsblock" genannt. Es wird eigentlich nur in jeden Konstruktor kopiert. – wchargin

+1

Diese Frage kann doppelte Frage sein: http://StackOverflow.com/Questions/16128076/Instance-Initialization-Block-and-Subclasses –

Antwort

22

Der Code innerhalb der geschweiften Klammern ohne Namen wird Teil des Konstruktors der Klasse sein und vor der im Klassenkonstruktor enthaltenen Logik ausgeführt.

Schnell Beispiel:

public class Foo { 
    { 
     System.out.println("Before Foo()"); 
    } 

    public Foo() { 
     System.out.println("Inside Foo()"); 
    } 

    { 
     System.out.println("Not After Foo()"); 
    } 
} 
+5

Es geht vor jedem Konstruktor. ('javap -c' wird dir das sagen.) – millimoose

+0

@millimoose true, Antwort behoben. –

+1

+1 für das Beispiel. – Maroun

3

Dies ist ein Instanz Initialisierungsbaustein die die Konstruktor vor läuft, und wenn Sie sich fragen, warum würde man will es anstelle des Konstruktor verwenden? Die Antwort ist nein, du nicht.

Nur frage mich, über den Grund der Code wie folgt kompilieren:

Sie verwenden es in der Regel gemeinsamen Code Faktor, wenn Konstruktor Überlastung. So bezieht sich der "der" oben tatsächlich auf einen der überladenen Konstruktoren, die auf Objekt Instanziierung nach die gemeinsame Instanz Initialisierung aufgerufen wird Code-Block ausgeführt hat.

Übrigens könnten Sie manchmal dasselbe erreichen, indem Sie einen Konstruktor von dem anderen aufrufen, aber der Aufruf muss dann in der ersten Zeile innerhalb des aufrufenden Konstruktors stehen oder der Code wird nicht kompiliert.

+0

Nein, natürlich wollte ich es nicht als Konstruktor verwenden. Es war nur ein reines Interesse, mehr nicht. Und danke für die Erklärung der Überladung des Konstruktors. – Oldestkon

+1

Gern geschehen. Das wirst du wahrscheinlich schon wissen. Es gibt auch statische Init-Blöcke, die verwendet werden, um statische Klassenmitglieder zu initialisieren. Und mehrere Blöcke werden in der Reihenfolge ausgeführt, in der sie in Ihrem Code erscheinen. –

+0

Ich kenne die Grundlagen bereits, im Moment lerne ich "die Tiefen" von Multi-Threading, wie volatile Vars, oder synchronisierte Blöcke. – Oldestkon

12

Dies wird als Instanzinitialisierer bezeichnet. Der Code im Initialisierer wird eingefügt nach der Aufruf an den Superklassenkonstruktor und vor der Rest des Konstruktorcodes.

Die erste Operation eines Konstruktors ist das Aufrufen eines Superklassenkonstruktors. Wenn ein Konstruktor explizit aufgerufen wird, super(...), wird der angegebene Konstruktor verwendet. Wenn kein Konstruktor explizit aufgerufen wird, wird der Standardkonstruktor (ohne Argumente) in der Superklasse aufgerufen. Wenn kein solcher Konstruktor vorhanden ist, handelt es sich um einen Kompilierzeitfehler.

Nach diesem expliziten oder impliziten Konstruktoraufruf werden Instanzinitialisierer in der Reihenfolge aufgerufen, in der sie im Quellcode angezeigt werden (ja, Sie können mehrere Initialisierer haben).

Zur Veranschaulichung dieses Programm druckt im initialisiert

 
Another constructor 
Init 1 
Init 2 
Test constructor 
class Another { 
    Another() { System.out.println("Another constructor"); } 
} 

class Test extends Another { 

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

    { System.out.println("Init 1"); } 

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

    { System.out.println("Init 2"); } 

} 

Die am häufigsten gesehen Anwendung der "double brace initialization" idiom, läuft, wo eine anonyme innere Klasse definiert ist, und eine Instanz erstellt und auf einmal konfiguriert.Hier ist ein recht häufiges Beispiel aus Swing-Programmierung:

JButton popupButton = new JButton(new AbstractAction("Popup") { 
    { 
    putValue(Action.SHORT_DESCRIPTION, "Popup a dialog"); 
    } 

    @Override 
    public void actionPerformed(ActionEvent evt) 
    { 
    popup(); 
    } 
}); 

Dies könnte nützlich sein, wenn Sie mehrere Konstrukteure haben, und müssen einige Parameter lose Initialisierung in jedem Konstruktor auszuführen. Dies könnte in einem Initialisierungsblock berücksichtigt werden.

+0

Diese Antwort erklärt die Reihenfolge, in der Instanzinitialisierer und Konstruktoren aufgerufen werden. Vielen Dank! –

Verwandte Themen