Heim >Java >javaLernprogramm >Anwendungsbeispiele für Java-Klassenlader und Klassenreflexion
1. Ein Befehl entspricht einem Prozess.
Wenn wir ein Java-Programm starten, das heißt, wenn wir eine Hauptmethode starten, wird ein Java Virtual Machine-Prozess gestartet, egal wie komplex der Prozess ist. Verschiedene JVM-Prozesse beeinflussen sich nicht gegenseitig. Aus diesem Grund wird gesagt, dass das Java-Programm nur einen Eingang hat – die Hauptmethode, die von der virtuellen Maschine aufgerufen wird. Die beiden Hauptmethoden entsprechen zwei JVM-Prozessen, die zwei verschiedene Klassenlader starten und tatsächlich unterschiedliche Klassen betreiben. Daher werden sie sich nicht gegenseitig beeinflussen.
2. Klassenladung.
Wenn wir eine Klasse verwenden und die Klasse nicht in den Speicher geladen wurde, initialisiert das System die Klasse durch Laden, Verbinden und Initialisieren.
1. Klassenladen: bezieht sich auf das Einlesen der Klassendatei der Klasse in die JVM und das Erstellen eines Klassenobjekts dafür.
2. Klassenverbindung: bezieht sich auf das Zusammenführen der Binärdaten der Klasse in die JRE, die in drei Phasen unterteilt ist:
a).
b) Vorbereitung: Weisen Sie den statischen Variablen der Klasse Speicherplatz zu und führen Sie die Standardinitialisierung durch.
c), Parsen: Ersetzen Sie Symbolreferenzen in den Binärdaten der Klasse durch direkte Referenzen.
3. Initialisierung: Initialisieren Sie die statischen Variablen und statischen Initialisierungsblöcke der Klasse.
(Hinweis: Wenn bei einer statischen Eigenschaft vom endgültigen Typ der Eigenschaftswert zur Kompilierungszeit abgerufen wurde, führt der Aufruf der Eigenschaft nicht dazu, dass die Klasse initialisiert wird, da dies der Verwendung einer Konstante entspricht;
Verwenden Sie die ClassLoader()-Methode, die die Klasse nur lädt und nicht initialisiert)
3.
Der Klassenlader ist dafür verantwortlich, .class-Dateien in den Speicher zu laden und entsprechende java.lang.Class-Objekte zu generieren. Sobald eine Klasse in die JVM geladen ist, wird sie nicht geladen wieder.
In Java wird eine Klasse durch ihren vollständig qualifizierten Klassennamen identifiziert (d. h. Paketname + Klassenname).
In der JVM wird eine Klasse durch ihren vollständig qualifizierten Klassennamen und ihren Klassenlader identifiziert.
JVM generiert beim Ausführen drei ClassLoader, nämlich: BootstrapClassLoader (Stammklassenlader), ExtClassLoader (erweiterter Klassenlader) und AppClassLoader (Systemklassenlader). Die UML-Struktur lautet wie folgt:
Unter anderem ist BootstrapClassLoader für das Laden der Kernklassenbibliothek von JRE verantwortlich. Es handelt sich nicht um eine Unterklasse von ClassLoader und ist in C++ geschrieben, also sind wir es. Es ist in Java nicht sichtbar und gibt null zurück, wenn es über die getParent()-Methode seiner Unterklasse abgerufen wird. BootstrapClassLoader ist für das Laden von Java-Kernklassenbibliotheken wie rt.jar und charsets.jar unter dem JRE-Ziel verantwortlich.
Wie aus der Abbildung ersichtlich ist, sind ExtClassLoader und AppClassLoader Unterklassen von ClassLoader. Sie können sie nicht in der API sehen, sie befinden sich in der Datei rt.jar. Die vollständig qualifizierten Klassennamen sind:
sun.misc.Launcher$ExtClassLoader und sun.misc.Launcher$AppClassLoader.
Unter diesen ist ExtClassLoader für das Laden des JAR-Pakets in der JRE-Erweiterung verantwortlich Verzeichnis ext und AppClassLoader Verantwortlich für das Laden von Klassenpaketen unter dem Classpath-Pfad.
Der Test ist wie folgt:
package com.stopTalking.crazy; public class TestClassLoader { public static void main(String[] args) { //获取当前线程的类装载器 ClassLoader loader = Thread.currentThread().getContextClassLoader(); //获取System类的类装载器 ClassLoader loader1 = System.class.getClassLoader(); //获取本类TestClassLoader的类装载器loader2 ClassLoader loader2 = TestClassLoader.class.getClassLoader(); //获取loader2的父类 ClassLoader loader3 = loader2.getParent(); //获取loader2的父类的父类 ClassLoader loader4 = loader3.getParent(); System.out.println(loader); System.out.println(loader1); System.out.println(loader2); System.out.println(loader3); System.out.println(loader4); } }
Konsolenausgabe:
//当前线程类获取的类加载器是AppClassLoader sun.misc.Launcher$AppClassLoader@6b97fd //System类为根装载器加载,java中访问不到,所以为null null //本类的类加载器当然也是AppClassLoader sun.misc.Launcher$AppClassLoader@6b97fd sun.misc.Launcher$ExtClassLoader@1c78e57 null
Weitere Artikel zu Java-Klassenladern und Klassenreflexionsverwendungsbeispielen finden Sie unter die chinesische PHP-Website!