Mich würd mal interessieren, wie der Java Compiler das folgende Beispiel abarbeitet und den richtigen statischen Block in UIUtil findet. Ich hab natürlich einiges gekürzt. Falls irgendwas keinen Sinn ergibt, bescheid sagen.
Es ist ja so, dass ein statischer Initialisierungsblock das erste Mal ausgeführt wird, sobald die Klasse geladen wird. Das passiert ja weder bei UIUtil.parseArgs(argv), TranslationBundle.parseArgs(args) oder Util.getResourceBundle(TranslationBundle.class,"foo",loc), weil alles statische Methoden sind. Erst sobald streamOpener.getResourceBundle(c,n,l) aufgerufen werden soll, wird der statische Initialisierungsblock in UIUtil ausgeführt. Wieso aber? Die Klasse ist doch immer noch nicht geladen, weil bisher nur statisch darauf zugegriffen wurde?! Ist natürlich klar, dass für streamOpener jetzt ein konkreter Typ her muss, aber woher weiß die JVM, dass sie genau in UIUtil suchen muss?
Merkt er sich das irgendwie oder gibts da ein bestimmtes Muster, nach dem er den Classpath abklappert? Sobald eine statische Methode aus UIUtil aufgerufen wird, hat streamOpener schon den Typ UIUtil$1. Was bedeutet das und wertet er den statischen Block also doch irgendwie schon vorher aus? Die Deklaration von streamOpener steht ja nur da?!
Es ist ja so, dass ein statischer Initialisierungsblock das erste Mal ausgeführt wird, sobald die Klasse geladen wird. Das passiert ja weder bei UIUtil.parseArgs(argv), TranslationBundle.parseArgs(args) oder Util.getResourceBundle(TranslationBundle.class,"foo",loc), weil alles statische Methoden sind. Erst sobald streamOpener.getResourceBundle(c,n,l) aufgerufen werden soll, wird der statische Initialisierungsblock in UIUtil ausgeführt. Wieso aber? Die Klasse ist doch immer noch nicht geladen, weil bisher nur statisch darauf zugegriffen wurde?! Ist natürlich klar, dass für streamOpener jetzt ein konkreter Typ her muss, aber woher weiß die JVM, dass sie genau in UIUtil suchen muss?
Merkt er sich das irgendwie oder gibts da ein bestimmtes Muster, nach dem er den Classpath abklappert? Sobald eine statische Methode aus UIUtil aufgerufen wird, hat streamOpener schon den Typ UIUtil$1. Was bedeutet das und wertet er den statischen Block also doch irgendwie schon vorher aus? Die Deklaration von streamOpener steht ja nur da?!
Java:
// CommandText.java
public static void main(String[] argv) {
UIUtil.parseArgs(argv);
}
// UiUtil.java
public class UIUtil {
static {
Util.streamOpener = new IO() {
...
}
public static void parseArgs(String[] args) {
TranslationBundle.parseArgs(args);
}
// TranslationBundle.java
public class TranslationBundle {
static public void parseArgs(String[] args) {
resBundle = Util.getResourceBundle(TranslationBundle.class,"foo",loc);
}
}
// Util.java
public class Util {
public static IO streamOpener;
public static ResourceBundle getResourceBundle(Class c,String n,Locale l) {
return streamOpener.getResourceBundle(c,n,l);
}
}
// IO.java
public interface IO {
ResourceBundle getResourceBundle(Class a,String n,Locale l);
}