Was ist der Unterschied zwischen der Initialisierung innerhalb eines static
Blocks:
public class staticTest {
static String s;
static int n;
static double d;
static {
s = "I'm static";
n = 500;
d = 4000.0001;
}
...
Und individuelle statische Initialisierung:
public class staticTest {
static String s = "I'm static";
static int n = 500;
static double d = 4000.0001;
....
java
static-initialization
Adam Matan
quelle
quelle
Antworten:
Ein statischer Initialisierungsblock ermöglicht eine komplexere Initialisierung, beispielsweise unter Verwendung von Bedingungen:
static double a; static { if (SomeCondition) { a = 0; } else { a = 1; } }
Oder wenn mehr als nur eine Konstruktion erforderlich ist: Wenn Sie zum Erstellen Ihrer Instanz einen Builder verwenden, ist eine Ausnahmebehandlung oder eine andere Arbeit als das Erstellen statischer Felder erforderlich.
Ein statischer Initialisierungsblock wird auch nach den statischen Inline-Initialisierern ausgeführt, sodass Folgendes gültig ist:
static double a; static double b = 1; static { a = b * 4; // Evaluates to 4 }
quelle
Eine typische Verwendung:
private final static Set<String> SET = new HashSet<String>(); static { SET.add("value1"); SET.add("value2"); SET.add("value3"); }
Wie würden Sie es ohne statischen Initialisierer tun?
quelle
SET
und verwenden Sie den Variableninitialisierer (private final static Set<String> SET = createValueSet()
). Was wäre, wenn Sie 5 Sätze und 2 Karten hätten, würden Sie alle einfach in einen einzigenstatic
Block werfen?Sie können den try / catch-Block
static{}
wie folgt verwenden:MyCode{ static Scanner input = new Scanner(System.in); static boolean flag = true; static int B = input.nextInt(); static int H = input.nextInt(); static{ try{ if(B <= 0 || H <= 0){ flag = false; throw new Exception("Breadth and height must be positive"); } }catch(Exception e){ System.out.println(e); } } }
PS: Davon verwiesen !
quelle
Die Ausnahmebehandlung während der Initialisierung ist ein weiterer Grund. Zum Beispiel:
static URL url; static { try { url = new URL("https://blahblah.com"); } catch (MalformedURLException mue) { //log exception or handle otherwise } }
Dies ist nützlich für Konstruktoren, die wie oben ärgerlich geprüfte Ausnahmen auslösen, oder für komplexere Initialisierungslogiken, die möglicherweise zu Ausnahmen neigen.
quelle
Manchmal möchten Sie mehr als nur statischen Variablen Werte zuweisen. Da Sie keine beliebigen Anweisungen in den Klassenkörper einfügen können, können Sie einen statischen Initialisierungsblock verwenden.
quelle
In Ihrem Beispiel gibt es keinen Unterschied. Oft ist der Anfangswert jedoch komplexer, als er bequem in einem einzelnen Ausdruck ausgedrückt werden kann (z. B. ist es
List<String>
einfor
Wert, dessen Inhalt am besten durch eine Schleife ausgedrückt wird ; oder ein WertMethod
, der möglicherweise nicht vorhanden ist, sodass Ausnahmebehandlungsroutinen erforderlich sind), und / oder Die statischen Felder müssen in einer bestimmten Reihenfolge festgelegt werden.quelle
static
Block kann verwendet werden, um eine Singleton- Instanz zu initialisieren , um die Verwendung einer synchronisiertengetInstance()
Methode zu verhindern .quelle
Technisch könnte man ohne davonkommen. Einige bevorzugen mehrzeiligen Initialisierungscode für eine statische Methode. Ich bin ziemlich glücklich, einen statischen Initialisierer für eine relativ einfache Initialisierung mit mehreren Anweisungen zu verwenden.
Natürlich würde ich fast immer meine Statik machen
final
und auf ein nicht veränderbares Objekt zeigen.quelle
Das statische Schlüsselwort (ob es sich um eine Variable oder einen Block handelt) gehört zur Klasse. Wenn die Klasse aufgerufen wird, werden diese Variablen oder Blöcke ausgeführt. Daher wird der größte Teil der Initialisierung mithilfe eines statischen Schlüsselworts durchgeführt. Da es zur Klasse selbst gehört, kann die Klasse direkt darauf zugreifen, ohne eine Instanz der Klasse zu erstellen.
Beispiel:
class Shoe { int size; String colour; static String brand = "Nike"; public Shoe(int size, String colour) { super(); this.size = size; this.colour = colour; } void displayShoe() { System.out.printf("%-2d %-8s %s %n",size,colour, brand); } public static void main(String args[]) { Shoe s1 = new Shoe(7, "Blue"); Shoe s2 = new Shoe(8, "White"); System.out.println("================="); s1.displayShoe(); s2.displayShoe(); System.out.println("================="); } }
quelle
Wir verwenden Konstruktoren, um unsere Instanzvariablen zu initialisieren (nicht statische Variablen, Variablen, die zu Objekten gehören, nicht die Klasse).
Wenn Sie Klassenvariablen (statische Variablen) initialisieren möchten und dies ohne Erstellen eines Objekts tun möchten (Konstruktoren können nur beim Erstellen eines Objekts aufgerufen werden), benötigen Sie statische Blöcke.
static Scanner input = new Scanner(System.in); static int widht; static int height; static { widht = input.nextInt(); input.nextLine(); height = input.nextInt(); input.close(); if ((widht < 0) || (height < 0)) { System.out.println("java.lang.Exception: Width and height must be positive"); } else { System.out.println("widht * height = " + widht * height); } }
quelle
System.out.println("B * H");
ist ziemlich nutzlos. Und die Antwort selbst ist ziemlich vage. OP erwähnte keine Konstruktoren oder Instanzvariablen.Der statische Codeblock ermöglicht es, die Felder mit mehr als einer Anweisung zu initialisieren, Felder in einer anderen Reihenfolge der Deklarationen zu initialisieren und kann auch zur bedingten Intialisierung verwendet werden.
Genauer,
static final String ab = a+b; static final String a = "Hello,"; static final String b = ", world";
funktioniert nicht, da a und b nach ab deklariert sind.
Ich könnte jedoch einen statischen Init verwenden. Block, um dies zu überwinden.
static final String ab; static final String a; static final String b; static { b = ", world"; a = "Hello"; ab = a + b; } static final String ab; static final String a; static final String b; static { b = (...) ? ", world" : ", universe"; a = "Hello"; ab = a + b; }
quelle
ab
Deklaration einfach unter die Deklaration von verschiebenb
.Ein statischer Initialisierungsblock ist nützlich, wenn Sie bestimmte statische Klassentypen vor der ersten Verwendung der Klasse initialisieren möchten. Bei einer späteren Verwendung werden keine statischen Initialisierungsblöcke aufgerufen. Es ist das direkte Gegenteil von Instanzinitialisierern, die Instanzmitglieder initialisieren.
quelle
Wenn Sie einen bestimmten Ausdruck während der Ladezeit der Klasse auswerten möchten, können Sie den statischen Block verwenden. Beachten Sie jedoch Folgendes:
quelle