Statische Initialisierungsblöcke


265

Soweit ich verstanden habe, wird der "statische Initialisierungsblock" verwendet, um Werte des statischen Feldes festzulegen, wenn dies nicht in einer Zeile möglich ist.

Aber ich verstehe nicht, warum wir dafür einen speziellen Block brauchen. Zum Beispiel deklarieren wir ein Feld als statisch (ohne Wertzuweisung). Schreiben Sie dann mehrere Zeilen des Codes, die einen Wert generieren und dem oben deklarierten statischen Feld einen Wert zuweisen.

Warum brauchen wir diese Zeilen in einem speziellen Block wie : static {...}?


6
Geringfügiges Feedback, aber es wäre hilfreich, wenn Sie Ihre Annahmen klar darlegen und daher klarstellen könnten, welche Antwort richtig ist. wenn ich zuerst die Frage lesen, ich falsch verstanden und dachte , dass Sie den Unterschied zwischen wußte {...}vs static {...}. (In diesem Fall hat Jon Skeet Ihre Frage definitiv besser beantwortet)
David T.

1
Diese Frage ist sehr unklar; Die Antwortenden kriechen und machen viele langatmige Vermutungen darüber, was Sie gemeint haben. Wie wäre es, wenn Sie den beispielhaften statischen Initialisierungsblock und Ihre Alternative explizit aufschreiben, damit die Leute etwas klares zu beantworten haben?
Don Hatch

Antworten:


430

Der nicht statische Block:

{
    // Do Something...
}

Wird jedes Mal aufgerufen, wenn eine Instanz der Klasse erstellt wird. Der statische Block wird nur einmal aufgerufen , wenn die Klasse selbst initialisiert wird, unabhängig davon, wie viele Objekte dieses Typs Sie erstellen.

Beispiel:

public class Test {

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

    {
        System.out.println("Non-static block");
    }

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

Dies druckt:

Static
Non-static block
Non-static block

106
Warum ist dies die akzeptierte Antwort? Es beantwortet nicht einmal die Frage.
Paul Bellora

43
Es beantwortet die Frage: "Dies wird jedes Mal aufgerufen, wenn die Klasse erstellt wird. Der statische Block wird nur einmal aufgerufen, unabhängig davon, wie viele Objekte dieses Typs Sie erstellen."
Adam Arold

83
Für den neugierigen Leser wird der nicht statische Block vom Java-Compiler tatsächlich in jeden Konstruktor der Klasse ( Quelle ) kopiert . Es ist also immer noch Aufgabe des Konstruktors, Felder zu initialisieren.
Martin Andersson

2
Die akzeptierte Antwort sollte folgende sein: stackoverflow.com/a/2420404/363573 . Diese Antwort zeigt ein Beispiel aus dem wirklichen Leben, in dem Sie statische Blöcke benötigen.
Stephan

16
Warum wird diese Antwort plötzlich abgelehnt? Sie sind vielleicht anderer Meinung, dass dies die akzeptierte Antwort ist, aber es ist sicherlich in keiner Weise falsch oder irreführend. Es wird lediglich versucht, das Verständnis dieser Sprachkonstrukte anhand eines einfachen Beispiels zu verbessern.
Frederik Wordenskjold

132

Wenn sie nicht in einem statischen Initialisierungsblock wären, wo wären sie? Wie würden Sie eine Variable deklarieren, die nur zum Zwecke der Initialisierung lokal sein sollte, und sie von einem Feld unterscheiden? Wie möchten Sie zum Beispiel schreiben:

public class Foo {
    private static final int widgets;

    static {
        int first = Widgets.getFirstCount();
        int second = Widgets.getSecondCount();
        // Imagine more complex logic here which really used first/second
        widgets = first + second;
    }
}

Wenn firstund secondnicht in einem Block, würden sie wie Felder aussehen. Wenn sie sich in einem Block ohne staticdavor befinden würden, würde dies als Instanzinitialisierungsblock anstelle eines statischen Initialisierungsblocks gelten, sodass er einmal pro konstruierter Instanz und nicht einmal insgesamt ausgeführt würde.

In diesem speziellen Fall können Sie stattdessen eine statische Methode verwenden:

public class Foo {
    private static final int widgets = getWidgets();

    static int getWidgets() {
        int first = Widgets.getFirstCount();
        int second = Widgets.getSecondCount();
        // Imagine more complex logic here which really used first/second
        return first + second;
    }
}

... aber das funktioniert nicht, wenn es mehrere Variablen gibt, die Sie innerhalb desselben Blocks zuweisen möchten, oder keine (z. B. wenn Sie nur etwas protokollieren oder eine native Bibliothek initialisieren möchten).


1
Tritt der statische Block vor oder nach der Zuweisung statischer Variablen auf? private static int widgets = 0; static{widgets = 2;}
Weishi Zeng

1
War neugierig, ob der statische Block vor oder nach der Zuweisung statischer Variablen auftritt. Beispiel: Es wurde private static int widgets = 0; static{widgets = 2;}festgestellt, dass die Zuweisung '=' in der richtigen Reihenfolge erfolgt, was bedeutet, dass das zuerst gesetzte '=' zuerst zugewiesen wird. Das obige Beispiel gibt 'Widgets' den Wert 2. (PS wusste nicht, dass Kommentare nur in 5 Minuten bearbeitet werden können ...)
Weishi Zeng

@ WeishiZeng: Ja, dies ist wie in docs.oracle.com/javase/specs/jls/se8/html/… dokumentiert - Punkt 9.
Jon Skeet

Aber könnten Sie nicht auch eine private statische Methode verwenden, die genau den gleichen Code wie der statische Initialisierungsblock hat, und der privaten statischen Methode Widgets zuweisen?
Zachary Kraus

1
@Zachary: Meinen Sie damit, den Wert zurückzugeben und das Ergebnis des Methodenaufrufs zuzuweisen? Wenn ja, ja - wenn Sie sind auf genau eine Variable , die als Ergebnis des Blocks zuweisen. Ich werde meine Antwort mit Details in ungefähr 7 Stunden bearbeiten ...
Jon Skeet

103

Hier ist ein Beispiel:

  private static final HashMap<String, String> MAP = new HashMap<String, String>();
  static {
    MAP.put("banana", "honey");
    MAP.put("peanut butter", "jelly");
    MAP.put("rice", "beans");
  }

Der Code in den Abschnitten "statisch" wird zur Ladezeit der Klasse ausgeführt, bevor Instanzen der Klasse erstellt werden (und bevor statische Methoden von einer anderen Stelle aufgerufen werden). Auf diese Weise können Sie sicherstellen, dass alle Klassenressourcen einsatzbereit sind.

Es ist auch möglich, nicht statische Initialisierungsblöcke zu haben. Diese verhalten sich wie Erweiterungen der für die Klasse definierten Konstruktormethoden. Sie sehen genauso aus wie statische Initialisierungsblöcke, außer dass das Schlüsselwort "static" weggelassen wird.


4
Für dieses spezielle Beispiel wurde manchmal das Doppelklammermuster "missbraucht" :)
BalusC

Es kann missbraucht werden, aber andererseits räumt es einige Unordnung auf und macht einige Arten von Code ein wenig "solider". Ich programmiere in Erlang zum Spaß, und Sie sind begeistert davon, keine lokalen Variablen zu benötigen :-)
Pointy

1
<< Der Code in den "statischen" Abschnitten wird zur Ladezeit der Klasse ausgeführt, bevor Instanzen der Klasse erstellt werden (und bevor statische Methoden von einer anderen Stelle aufgerufen werden). Auf diese Weise können Sie sicherstellen, dass alle Klassenressourcen einsatzbereit sind. >> (Welches "Pointy" in der obigen Antwort erwähnt wurde) Dies ist ein sehr wichtiger Punkt, der bei der Ausführung statischer Blöcke zu beachten ist.
Lerner

Können wir dies mit InitializingBean nach der afterPropertiesSet-Methode tun?
Egemen

48

Dies ist auch nützlich, wenn Sie den Wert eigentlich nichts zuweisen möchten, z. B. wenn Sie eine Klasse zur Laufzeit nur einmal laden .

Z.B

static {
    try {
        Class.forName("com.example.jdbc.Driver");
    } catch (ClassNotFoundException e) {
        throw new ExceptionInInitializerError("Cannot load JDBC driver.", e);
    }
}

Hey, es gibt noch einen weiteren Vorteil, mit dem Sie Ausnahmen behandeln können. Stellen Sie sich vor, dass getStuff()hier ein Exceptionwas wirklich wirft in einen Fangblock gehört:

private static Object stuff = getStuff(); // Won't compile: unhandled exception.

dann ein static ist hier Initialisierer nützlich. Dort können Sie die Ausnahme behandeln.

Ein anderes Beispiel ist, danach Dinge zu tun, die während der Zuweisung nicht erledigt werden können:

private static Properties config = new Properties();

static {
    try { 
        config.load(Thread.currentThread().getClassLoader().getResourceAsStream("config.properties");
    } catch (IOException e) {
        throw new ExceptionInInitializerError("Cannot load properties file.", e);
    }
}

Um zum Beispiel des JDBC-Treibers zurückzukehren, verwendet jeder anständige JDBC-Treiber selbst auch den staticInitialisierer, um sich im zu registrieren DriverManager. Siehe auch diese und diese Antwort.


2
Hierin liegt gefährliches Voodoo ... statische Initialisierer werden in der synthetischen Clinit () -Methode ausgeführt, die implizit synchronisiert ist . Dies bedeutet, dass die JVM eine Sperre für die betreffende Klassendatei erhält. Dies kann in Multithread-Umgebungen zu einem Deadlock führen, wenn zwei Klassen versuchen, sich gegenseitig zu laden, und jede in einen anderen Thread geladen wird. Siehe www-01.ibm.com/support/docview.wss?uid=swg1IV48872
Ajax

@ Ajax: Ich würde dies als Fehler entweder im fraglichen JDBC-Treiber oder im Anwendungscode betrachten, der für das Laden verantwortlich ist. Bei anständigen JDBC-Treibern ist normalerweise nichts von Bedeutung, solange Sie sie beim Start der Anwendung nur einmal anwendungsweit laden.
BalusC

Es wäre sicherlich ein Fehler, aber nicht ganz die Schuld des JDBC-Treibers. Vielleicht hat der Treiber unschuldig seine eigenen statischen Initialisierer, und vielleicht initialisieren Sie diese Klasse unschuldig zusammen mit einigen anderen in Ihrer App, und oh nein, einige unerwartete Klassen laden sich zyklisch gegenseitig, und jetzt blockiert Ihre App. Ich habe dies dank eines Deadlocks zwischen java.awt.AWTEvent und sun.util.logging.PlatformLogger entdeckt. Ich habe AWTEvent nur berührt, um zu sagen, dass es kopflos laufen soll, und eine andere Bibliothek hat PlatformLogger geladen ... was AWTEvent auch lädt.
Ajax

1
Beide Klassen wurden synchronisiert auf verschiedenen Threads abgeschlossen, und mein Build war ungefähr 1/150 Mal blockiert. Daher bin ich jetzt beim Laden von Klassen in statischen Blöcken viel vorsichtiger. In dem oben erwähnten Fall, indem ich ein verzögertes Anbietermuster verwende, bei dem ich sofort eine vorläufige Anbieterklasse erstellen kann (ohne die Möglichkeit eines Deadlocks), das Feld initialisieren und dann, wenn tatsächlich darauf zugegriffen wird (bei einem nicht synchronisierten Feldzugriff), dann lade ich tatsächlich die Klassen, die den Deadlock verursachen können.
Ajax

11

Ich würde sagen, es static blockist nur syntaktischer Zucker. Mit staticBlock und nichts anderem kann man nichts anfangen.

Um einige hier veröffentlichte Beispiele wiederzuverwenden.

Dieser Code kann ohne Verwendung des staticInitialisierers neu geschrieben werden .

Methode 1: Mit static

private static final HashMap<String, String> MAP;
static {
    MAP.put("banana", "honey");
    MAP.put("peanut butter", "jelly");
    MAP.put("rice", "beans");
  }

Methode 2: Ohne static

private static final HashMap<String, String> MAP = getMap();
private static HashMap<String, String> getMap()
{
    HashMap<String, String> ret = new HashMap<>();
    ret.put("banana", "honey");
    ret.put("peanut butter", "jelly");
    ret.put("rice", "beans");
    return ret;
}

10

Es gibt einige tatsächliche Gründe, aus denen es existieren muss:

  1. Initialisieren von static finalMitgliedern, deren Initialisierung möglicherweise eine Ausnahme auslöst
  2. Elemente static finalmit berechneten Werten initialisieren

Benutzer verwenden static {}Blöcke in der Regel als bequeme Methode, um Dinge zu initialisieren, von denen die Klasse auch innerhalb der Laufzeit abhängt - beispielsweise um sicherzustellen, dass eine bestimmte Klasse geladen ist (z. B. JDBC-Treiber). Das kann auf andere Weise geschehen; Die beiden oben genannten Dinge können jedoch nur mit einem Konstrukt wie dem static {}Block ausgeführt werden.


8

Sie können Codebits einmal für eine Klasse ausführen, bevor ein Objekt in den statischen Blöcken erstellt wird.

Z.B

class A {
  static int var1 = 6;
  static int var2 = 9;
  static int var3;
  static long var4;

  static Date date1;
  static Date date2;

  static {
    date1 = new Date();

    for(int cnt = 0; cnt < var2; cnt++){
      var3 += var1;
    }

    System.out.println("End first static init: " + new Date());
  }
}

7

Es ist ein weit verbreitetes Missverständnis zu glauben, dass ein statischer Block nur Zugriff auf statische Felder hat. Dazu möchte ich im Folgenden einen Teil des Codes zeigen, den ich häufig in realen Projekten verwende (teilweise aus einer anderen Antwort in einem etwas anderen Kontext kopiert ):

public enum Language { 
  ENGLISH("eng", "en", "en_GB", "en_US"),   
  GERMAN("de", "ge"),   
  CROATIAN("hr", "cro"),   
  RUSSIAN("ru"),
  BELGIAN("be",";-)");

  static final private Map<String,Language> ALIAS_MAP = new HashMap<String,Language>(); 
  static { 
    for (Language l:Language.values()) { 
      // ignoring the case by normalizing to uppercase
      ALIAS_MAP.put(l.name().toUpperCase(),l); 
      for (String alias:l.aliases) ALIAS_MAP.put(alias.toUpperCase(),l); 
    } 
  } 

  static public boolean has(String value) { 
    // ignoring the case by normalizing to uppercase
    return ALIAS_MAP.containsKey(value.toUpper()); 
  } 

  static public Language fromString(String value) { 
    if (value == null) throw new NullPointerException("alias null"); 
    Language l = ALIAS_MAP.get(value); 
    if (l == null) throw new IllegalArgumentException("Not an alias: "+value); 
    return l; 
  } 

  private List<String> aliases; 
  private Language(String... aliases) { 
    this.aliases = Arrays.asList(aliases); 
  } 
} 

Hier wird der Initialisierer verwendet, um einen Index ( ALIAS_MAP) zu verwalten und eine Reihe von Aliasen wieder dem ursprünglichen Aufzählungstyp zuzuordnen. Es ist als Erweiterung der integrierten valueOf-Methode gedacht, die von sich Enumselbst bereitgestellt wird .

Wie Sie sehen können, greift der statische Initialisierer sogar auf das privateFeld zu aliases. Es ist wichtig zu verstehen, dass der staticBlock bereits Zugriff auf die EnumWertinstanzen hat (z ENGLISH. B. ). Dies liegt daran, dass die Reihenfolge der Initialisierung und Ausführung bei EnumTypen so ist , als ob die static privateFelder mit Instanzen initialisiert wurden, bevor die staticBlöcke aufgerufen wurden:

  1. Die EnumKonstanten, die implizite statische Felder sind. Dies erfordert den Enum-Konstruktor und die Instanzblöcke, und die Instanzinitialisierung muss ebenfalls zuerst erfolgen.
  2. static Blockierung und Initialisierung statischer Felder in der Reihenfolge ihres Auftretens.

Diese Initialisierung außerhalb der Reihenfolge (Konstruktor vor staticBlock) ist wichtig zu beachten. Es passiert auch, wenn wir statische Felder mit den Instanzen ähnlich einem Singleton initialisieren (Vereinfachungen vorgenommen):

public class Foo {
  static { System.out.println("Static Block 1"); }
  public static final Foo FOO = new Foo();
  static { System.out.println("Static Block 2"); }
  public Foo() { System.out.println("Constructor"); }
  static public void main(String p[]) {
    System.out.println("In Main");
    new Foo();
  }
}

Was wir sehen, ist die folgende Ausgabe:

Static Block 1
Constructor
Static Block 2
In Main
Constructor

Klar ist, dass die statische Initialisierung tatsächlich vor dem Konstruktor und sogar danach erfolgen kann:

Durch einfachen Zugriff auf Foo in der Hauptmethode wird die Klasse geladen und die statische Initialisierung gestartet. Im Rahmen der statischen Initialisierung rufen wir jedoch erneut die Konstruktoren für die statischen Felder auf. Danach wird die statische Initialisierung fortgesetzt und der aus der Hauptmethode aufgerufene Konstruktor vervollständigt. Ziemlich komplexe Situation, für die ich hoffe, dass wir uns bei normaler Codierung nicht damit befassen müssen.

Weitere Informationen hierzu finden Sie im Buch " Effective Java ".


1
Der Zugriff auf aliasesbedeutet nicht, dass der statische Block auf nicht statische Mitglieder zugreifen kann. aliasesDer Zugriff erfolgt über die Languagevon der / static / values()-Methode zurückgegebenen Werte . Wie Sie bereits erwähnt haben, ist die Tatsache, dass die Enum-Variablen zu diesem Zeitpunkt bereits verfügbar sind, das ungewöhnliche Bit - nicht statische Mitglieder regulärer Klassen wären in dieser Situation nicht zugänglich.
Ignazio

Der statische Block greift weiterhin nur auf statische Felder zu (im Fall Ihrer Aufzählung ENGLISH, GERMAN, ...), die in diesem Fall Objekte sind. Da die statischen Felder selbst Objekte sind, können Sie auf das Instanzfeld des statischen Objekts zugreifen.
Swami PR

1
class Foo { static final Foo Inst1; static final Foo Inst2; static{ Inst1 = new Foo("Inst1"); Inst2 = new Foo("Inst2"); } static { System.out.println("Inst1: " + Inst1.member); System.out.println("Inst2: " + Inst2.member); } private final String member; private Foo(String member){ this.member = member; } } Der obige Code unterscheidet sich nicht vom Enum-Beispiel und ermöglicht weiterhin den Zugriff auf Instanzvariablen innerhalb des statischen Blocks
Swami PR

@ SwamiPR kompiliert es tatsächlich zu meiner Überraschung und ich muss zustimmen, dass der Code im Prinzip nicht anders ist. Ich muss die Java-Spezifikation erneut lesen. Ich habe das Gefühl, dass ich etwas verpasst habe. Gute Antwort zurück, danke.
YoYo

@ SwamiPR Das Problem ist wirklich, dass wir eine verwenden sollten Enum. Dies ist der beste Weg, um sicherzustellen, dass wir auf einzelne Instanzen verweisen hier . Und zu Ihren Punkten habe ich mehrere Aktualisierungen vorgenommen.
YoYo

3

Wenn Ihre statischen Variablen zur Laufzeit festgelegt werden müssen, ist ein static {...}Block sehr hilfreich.

Zum Beispiel, wenn Sie das statische Element auf einen Wert setzen müssen, der in einer Konfigurationsdatei oder Datenbank gespeichert ist.

Auch nützlich, wenn Sie einem statischen Element Werte hinzufügen möchten, Mapda Sie diese Werte in der ursprünglichen Elementdeklaration nicht hinzufügen können.


3

Sie haben also ein statisches Feld (es wird auch als "Klassenvariable" bezeichnet, da es eher zur Klasse als zu einer Instanz der Klasse gehört; mit anderen Worten, es ist eher der Klasse als einem Objekt zugeordnet) und Sie möchten es initialisieren. Wenn Sie also KEINE Instanz dieser Klasse erstellen und dieses statische Feld bearbeiten möchten, können Sie dies auf drei Arten tun:

1- Initialisieren Sie es einfach, wenn Sie die Variable deklarieren:

static int x = 3;

2- Haben Sie einen statischen Initialisierungsblock:

static int x;

static {
 x=3;
}

3- Haben Sie eine Klassenmethode (statische Methode), die auf die Klassenvariable zugreift und diese initialisiert: Dies ist die Alternative zum obigen statischen Block; Sie können eine private statische Methode schreiben:

public static int x=initializeX();

private static int initializeX(){
 return 3;
}

Warum sollten Sie nun statische Initialisierungsblöcke anstelle statischer Methoden verwenden?

Es liegt wirklich an dem, was Sie in Ihrem Programm brauchen. Sie müssen jedoch wissen, dass der statische Initialisierungsblock einmal aufgerufen wird. Der einzige Vorteil der Klassenmethode besteht darin, dass sie später wiederverwendet werden können, wenn Sie die Klassenvariable neu initialisieren müssen.

Angenommen, Sie haben ein komplexes Array in Ihrem Programm. Sie initialisieren es (mit for z. B. Schleife) und dann ändern sich die Werte in diesem Array im gesamten Programm, aber irgendwann möchten kehren Sie zum Anfangswert zurück). In diesem Fall können Sie die private statische Methode aufrufen. Falls Sie in Ihrem Programm keine Neuinitialisierung der Werte benötigen, können Sie einfach den statischen Block verwenden und benötigen keine statische Methode, da Sie sie später im Programm nicht mehr verwenden werden.

Hinweis: Die statischen Blöcke werden in der Reihenfolge aufgerufen, in der sie im Code erscheinen.

Beispiel 1:

class A{
 public static int a =f();

// this is a static method
 private static int f(){
  return 3;
 }

// this is a static block
 static {
  a=5;
 }

 public static void main(String args[]) {
// As I mentioned, you do not need to create an instance of the class to use the class variable
  System.out.print(A.a); // this will print 5
 }

}

Beispiel 2:

class A{
 static {
  a=5;
 }
 public static int a =f();

 private static int f(){
  return 3;
 }

 public static void main(String args[]) {
  System.out.print(A.a); // this will print 3
 }

}

0

Als Ergänzung, wie @Pointy sagte

Der Code in den Abschnitten "statisch" wird zur Ladezeit der Klasse ausgeführt, bevor Instanzen der Klasse erstellt werden (und bevor statische Methoden von einer anderen Stelle aufgerufen werden).

Es soll System.loadLibrary("I_am_native_library")in statischen Block hinzufügen .

static{
    System.loadLibrary("I_am_a_library");
}

Es wird garantiert, dass keine native Methode aufgerufen wird, bevor die zugehörige Bibliothek in den Speicher geladen wird.

Laut loadLibrary von oracle :

Wenn diese Methode mehrmals mit demselben Bibliotheksnamen aufgerufen wird, werden der zweite und die nachfolgenden Aufrufe ignoriert.

Daher wird das Setzen von System.loadLibrary nicht ganz unerwartet verwendet, um zu vermeiden, dass die Bibliothek mehrmals geladen wird.


0

Sie müssen zunächst verstehen, dass Ihre Anwendungsklassen selbst zur java.class.ClassLaufzeit für Objekte instanziiert werden. In diesem Fall werden Ihre statischen Blöcke ausgeführt. Sie können dies also tatsächlich tun:

public class Main {

    private static int myInt;

    static {
        myInt = 1;
        System.out.println("myInt is 1");
    }

    //  needed only to run this class
    public static void main(String[] args) {
    }

}

und es würde "myInt is 1" zur Konsole drucken. Beachten Sie, dass ich keine Klasse instanziiert habe.


0
static int B,H;
static boolean flag = true;
static{
    Scanner scan = new Scanner(System.in);
    B = scan.nextInt();
    scan.nextLine();
    H = scan.nextInt();

    if(B < 0 || H < 0){
        flag = false;
        System.out.println("java.lang.Exception: Breadth and height must be positive");
    } 
}

-1

Der statische Block wird für jede Technologie verwendet, um statische Datenelemente auf dynamische Weise zu initialisieren, oder wir können sagen, dass für die dynamische Initialisierung von statischen Datenelementen statische Blöcke verwendet werden. Für die nicht statische Datenelementinitialisierung haben wir einen Konstruktor, den wir jedoch nicht haben Jeder Ort, an dem wir statische Datenelemente dynamisch initialisieren können

Eg:-class Solution{
         // static int x=10;
           static int x;
       static{
        try{
          x=System.out.println();
          }
         catch(Exception e){}
        }
       }

     class Solution1{
      public static void main(String a[]){
      System.out.println(Solution.x);
        }
        }

Jetzt wird mein statisches int x dynamisch initialisiert. Bcoz, wenn der Compiler zu Solution.x wechselt, lädt er die Lösungsklasse und den statischen Block beim Laden der Klasse. So können wir dieses statische Datenelement dynamisch initialisieren.

}}

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.