380 Stimmen

Was ist der Unterschied zwischen einem statischen und einem nicht-statischen Initialisierungscodeblock?

Meine Frage bezieht sich auf eine bestimmte Verwendung des statischen Schlüsselworts. Es ist möglich, zu verwenden static Schlüsselwort, um einen Codeblock innerhalb einer Klasse abzudecken, der nicht zu einer Funktion gehört. Zum Beispiel lässt sich der folgende Code kompilieren:

public class Test {
    private static final int a;    
    static {
        a = 5;
        doSomething(a);
    }
    private static int doSomething(int x) {
        return (x+5);
    }
}

Wenn Sie die static beschwert es sich, weil die Variable a es final . Es ist jedoch möglich, beides zu entfernen final y static und kompilieren lassen.

Das ist für mich in beiderlei Hinsicht verwirrend. Wie soll ich einen Codeabschnitt haben, der zu keiner Methode gehört? Wie ist es möglich, ihn aufzurufen? Was ist überhaupt der Zweck dieser Verwendung? Oder besser, wo kann ich eine Dokumentation dazu finden?

10voto

Vincent Ramdhanie Punkte 100426

Sie werden keinen Code in einen statischen Block schreiben, der irgendwo in Ihrem Programm aufgerufen werden muss. Wenn der Code aufgerufen werden soll, müssen Sie ihn in einer Methode unterbringen.

Sie können statische Initialisierungsblöcke schreiben, um statische Variablen zu initialisieren, wenn die Klasse geladen wird, aber dieser Code kann komplexer sein

Ein statischer Initialisierungsblock sieht aus wie eine Methode ohne Namen, ohne Argumente und ohne Rückgabetyp. Da er nie aufgerufen wird, braucht er auch keinen Namen. Das einzige Mal, dass er aufgerufen wird, ist, wenn die virtuelle Maschine die Klasse lädt.

7voto

cardman Punkte 79

Wenn ein Entwickler einen Initialisierungsblock verwendet, kopiert der Java Compiler den Initialisierer in jeden Konstruktor der aktuellen Klasse.

den folgenden Code:

class MyClass {

    private int myField = 3;
    {
        myField = myField + 2;
        //myField is worth 5 for all instance
    }

    public MyClass() {
        myField = myField * 4;
        //myField is worth 20 for all instance initialized with this construtor
    }

    public MyClass(int _myParam) {
        if (_myParam > 0) {
            myField = myField * 4;
            //myField is worth 20 for all instance initialized with this construtor
            //if _myParam is greater than 0
        } else {
            myField = myField + 5;
            //myField is worth 10 for all instance initialized with this construtor
            //if _myParam is lower than 0 or if _myParam is worth 0
        }
    }

    public void setMyField(int _myField) {
        myField = _myField;
    }

    public int getMyField() {
        return myField;
    }
}

public class MainClass{

    public static void main(String[] args) {
        MyClass myFirstInstance_ = new MyClass();
        System.out.println(myFirstInstance_.getMyField());//20
        MyClass mySecondInstance_ = new MyClass(1);
        System.out.println(mySecondInstance_.getMyField());//20
        MyClass myThirdInstance_ = new MyClass(-1);
        System.out.println(myThirdInstance_.getMyField());//10
    }
}

ist gleichbedeutend mit:

class MyClass {

    private int myField = 3;

    public MyClass() {
        myField = myField + 2;
        myField = myField * 4;
        //myField is worth 20 for all instance initialized with this construtor
    }

    public MyClass(int _myParam) {
        myField = myField + 2;
        if (_myParam > 0) {
            myField = myField * 4;
            //myField is worth 20 for all instance initialized with this construtor
            //if _myParam is greater than 0
        } else {
            myField = myField + 5;
            //myField is worth 10 for all instance initialized with this construtor
            //if _myParam is lower than 0 or if _myParam is worth 0
        }
    }

    public void setMyField(int _myField) {
        myField = _myField;
    }

    public int getMyField() {
        return myField;
    }
}

public class MainClass{

    public static void main(String[] args) {
        MyClass myFirstInstance_ = new MyClass();
        System.out.println(myFirstInstance_.getMyField());//20
        MyClass mySecondInstance_ = new MyClass(1);
        System.out.println(mySecondInstance_.getMyField());//20
        MyClass myThirdInstance_ = new MyClass(-1);
        System.out.println(myThirdInstance_.getMyField());//10
    }
}

Ich hoffe, mein Beispiel wird von den Entwicklern verstanden.

5voto

Paul Tomblin Punkte 172816

Der statische Codeblock kann zur Instanziierung oder Initialisierung von Klassenvariablen (im Gegensatz zu Objektvariablen) verwendet werden. Wenn Sie also "a" als statisch deklarieren, bedeutet dies, dass es nur eine einzige Variable gibt, die von allen Testobjekten gemeinsam genutzt wird, und der statische Codeblock initialisiert "a" nur einmal, wenn die Testklasse zum ersten Mal geladen wird, unabhängig davon, wie viele Testobjekte erstellt werden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X