Ich habe 2 Gläser, nennen wir sie a.jar und b.jar.
b.jar hängt von a.jar ab.
In a.jar habe ich eine Klasse definiert, nennen wir sie StaticClass. In der StaticClass habe ich einen statischen Block definiert und eine Methode namens "init" aufgerufen:
public class StaticClass {
static {
init();
}
public void static init () {
// do some initialization here
}
}
in b.jar habe ich ein main, also erwarte ich im main, dass die init () -Methode aufgerufen wurde, aber eigentlich nicht. Ich vermute, das liegt daran, dass die StaticClass nicht von der JVM geladen wurde, könnte mir jemand sagen
- Ist meine Schlussfolgerung richtig?
- Was veranlasst das JVM, eine Klasse zu laden?
- Wie kann ich den statischen Block automatisch ausführen lassen?
Vielen Dank
Antworten:
Ja, du hast recht. Statische Initialisierungsblöcke werden ausgeführt, wenn der JVM (Class Loader - um genau zu sein) geladen wird
StaticClass
(was beim ersten Referenzieren im Code der Fall ist).Sie können das Aufrufen dieser Methode erzwingen, indem Sie explizit aufrufen. Dies
StaticClass.init()
ist der Verwendung der JVM vorzuziehen.Sie können auch versuchen
Class.forName(String)
, die JVM zu zwingen, die Klasse zu laden und ihre statischen Blöcke aufzurufen.quelle
javac
. Daher gibt es vom Standpunkt von JVM aus keinen wirklichen "Zugang". Dadurch ist das Verhalten verständlich. Ich möchte nur einen Kontext hinzufügen. Was Sie gesagt haben, ist sicherlich richtig.Ja, Sie haben Recht, da Sie Ihr nicht verwenden
StaticClass
, wird es nicht von der VM geladen und daherinit()
nie ausgeführt.Bei Ihrer zweiten Frage müssen Sie wahrscheinlich den harten Weg gehen und alle verfügbaren Klassen scannen und laden.
https://stackoverflow.com/a/3223019/393657
quelle
Zunächst unterscheidet sich das Laden von Klassen von der Klasseninitialisierung. Für alle, die nach Erklärungen aus der Java-Sprachspezifikation suchen, wann ein statischer Block ausgeführt wird - hier ist er.
Der JLS §8.7 sagt, dass:
Was bedeutet die Initialisierung? Wir verweisen auf JLS §12.4.2 . Dies beschreibt ein detailliertes Initialisierungsverfahren. Punkt JLS §12.4.1 könnte hier jedoch angemessener sein. Es steht dass :
Damit der statische Initialisierungsblock automatisch ausgeführt wird, müssen Sie eine dieser Optionen erzwingen.
quelle
Sie haben Recht, der einfachste Weg ist, auf die Klasse zuzugreifen, zum Beispiel a
StaticClass.class.newInstance();
Oder etwas in dieser Hinsicht in Ihrer Hauptmethode. Dadurch wird sichergestellt, dass die Klasse vom Klassenladeprogramm geladen wird.
quelle
Der statische Code wird ausgeführt, wenn auf Ihre Klasse (
StaticClass
glaube ich) verwiesen wird.Daher sollte es ausgeführt werden, wenn Sie eine neue Instanz von erstellen
StaticClass
oder eine der statischen Methoden aufrufen .quelle
Der statische Block wird ausgeführt, wenn eine geladene Klasse zuerst initialisiert oder referenziert wird. Das Laden einer Klasse bedeutet nicht, dass die Klasse initialisiert werden soll. Das Laden der JVM-Klasse ist ein separates Problem.
quelle
Ja, der statische Initialisierer wird ausgeführt, wenn die Klasse geladen wird. Dies tritt normalerweise auf, wenn Sie zum ersten Mal im Klassenladekontext auf die Klasse zugreifen.
quelle
In der Hauptmethodenklasse b.jar sollte diese StaticClass erweitert werden, dann werden automatisch der statische Block und init () aufgerufen
quelle
Weitere hinzufügen:
Der statische Block wird ausgeführt, wenn die JVM-Ladeklasse verwendet wird.
Hier in Ihrem Beispiel können Sie die
init()
Methode vonStaticClass
durch Aufrufen der Klasse aufrufenwie StaticClass staticClass = new StaticClass ();
oder
StaticClass.class.newInstance();
das ist mehr bevorzugtquelle