Ich habe eine Set-Klasse (Dies ist J2ME, also habe ich begrenzten Zugriff auf die Standard-API; nur um meine scheinbare Rad-Neuerfindung zu erklären). Ich verwende meine Set-Klasse, um konstante Mengen von Dingen in Klassen und Unterklassen zu erstellen. Es sieht ein bisschen wie dieses ...Kann ich die Reihenfolge garantieren, in der statische Initialisierer in Java ausgeführt werden?
class ParentClass
{
protected final static Set THE_SET = new Set() {{
add("one");
add("two");
add("three");
}};
}
class SubClass extends ParentClass
{
protected final static Set THE_SET = new Set() {{
add("four");
add("five");
add("six");
union(ParentClass.THE_SET); /* [1] */
}};
}
Alle sieht gut aus, mit Ausnahme der Linie bei [1], um eine Null-Zeiger-Ausnahme verursacht. Vermutlich bedeutet dies, dass der statische Initialisierer in der Unterklasse vor dem der übergeordneten Klasse ausgeführt wird. Das hat mich überrascht, weil ich gedacht hätte, dass es die statischen Blöcke in jedem neuen Import zuerst ausführen würde, bevor es in der instatiated Subklasse ausgeführt wird.
Bin ich richtig in dieser Annahme? Gibt es eine Möglichkeit, dieses Verhalten zu kontrollieren oder zu umgehen?
Update:
Die Dinge sind noch seltsamer. Ich habe versucht, diese stattdessen (Man beachte die ‚neue Parent()‘ Zeile):
class ParentClass
{
public ParentClass()
{
System.out.println(THE_SET);
}
protected final static Set THE_SET = new Set() {{
add("one");
add("two");
add("three");
}};
}
class SubClass extends ParentClass
{
protected final static Set THE_SET = new Set() {{
System.out.println("a");
new ParentClass();
System.out.println("b");
add("four");
System.out.println("c");
add("five");
System.out.println("d");
add("six");
System.out.println("e");
union(ParentClass.THE_SET); /* [1] */
System.out.println("f");
}};
}
Und der Ausgang ist seltsam:
a
["one", "two", "three"]
b
c
d
e
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.NullPointerException
So Parent wird initialisiert, aber die Unterklasse haben keinen Zugriff auf es in seinem statischen Initialisierer.
Ja ... das macht das Gleiche. – izb
Ich denke, Elijah hat es richtig gemacht. Dies ist kein Problem der Initialisierungsreihenfolge, sondern eher eine Art Namenskonflikt. – boutta
In meinem echten Code habe ich tatsächlich 3 Klassen, wobei A <-B <-C ist. Die Ausnahme war in B. Interessant, jeder Klasse einen eigenen Gruppennamen zu geben, verschiebt die Ausnahme nach C, löst das Problem jedoch nicht. Das bedeutet einfach, dass die Reihenfolge wirklich unvorhersehbar ist. – izb