Eine von einem statischen Intialisierer ausgelöste Ausnahme kann auf ein Designproblem hinweisen. Sie sollten wirklich nicht versuchen, Dateien in Statics zu laden. Auch statisch sollte im Allgemeinen nicht veränderbar sein.
Wenn man zum Beispiel mit JUnit 3.8.1 arbeitete, konnte man es fast von einem Applet/WebStart aus verwenden, aber es scheiterte an einem statischen Initialisierer, der Dateizugriffe durchführte. Der Rest der betroffenen Klasse passte gut in den Kontext, nur dieser Teil der Statik passte nicht in den Kontext und machte das ganze Framework kaputt.
Es gibt einige legitime Fälle, in denen eine Ausnahme ausgelöst wird. Wenn es sich um einen Fall handelt, in dem die Umgebung eine bestimmte Funktion nicht hat, z.B. weil es sich um ein altes JDK handelt, dann möchten Sie vielleicht Implementierungen ersetzen, und es ist nichts Ungewöhnliches. Wenn die Klasse wirklich defekt ist, werfen Sie eine ungeprüfte Ausnahme, anstatt eine defekte Klasse existieren zu lassen.
Je nach Vorliebe und Problemstellung gibt es zwei gängige Möglichkeiten, dies zu umgehen: ein expliziter statischer Initialisierer und eine statische Methode. (Ich, und ich denke die meisten Leute, bevorzugen Ersteres; ich glaube, Josh Bloch bevorzugt Letzteres).
private static final Thing thing;
static {
try {
thing = new Thing();
} catch (CheckedThingException exc) {
throw new Error(exc);
}
}
Oder
private static final Thing thing = newThing();
private static Thing newThing() {
try {
return new Thing();
} catch (CheckedThingException exc) {
throw new Error(exc);
}
}
Hinweis: Statics sollten endgültig (und im Allgemeinen unveränderlich) sein. Da sie endgültig sind, wird die korrekte Zuweisung von Ihrem freundlichen Compiler überprüft. Definitive Zuweisung bedeutet, dass es zu einer fehlerhaften Ausnahmebehandlung kommen kann - wrap and throw, do not print/log. Seltsamerweise können Sie den Klassennamen nicht verwenden, um die Initialisierung mit dem Klassennamen im statischen Initialisierer zu qualifizieren (ich bin sicher, es gibt einen guten Grund dafür).
Instanzinitialisierer sind ähnlich, allerdings kann man den Konstruktor zum Throw machen oder den Initialisierer im Konstruktor unterbringen.