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. Deshalb werden sie sich nicht gegenseitig beeinflussen.
2. Laden der Klasse.
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 Lesen der Klassendatei der Klasse in die JVM und das Erstellen eines Klassenobjekts dafür.
2. Klassenverbindung: Bezieht sich auf die Zusammenführung der Binärdaten der Klasse in der JRE, die in drei Phasen unterteilt ist:
a) Überprüfung: Überprüfen Sie die Richtigkeit der geladenen Klassendateidaten.
b) Vorbereitung: Weisen Sie den statischen Variablen der Klasse Speicherplatz zu und führen Sie eine Standardinitialisierung durch.
c) Parsen: Ersetzen Sie die 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 zu einer Initialisierung der Klasse, da dies der Verwendung einer Konstante entspricht.
Die Verwendung der ClassLoader()-Methode lädt nur die Klasse und initialisiert sie nicht. )
3. Klassenlader.
Der Klassenlader ist für das Laden von .class-Dateien in den Speicher und das Generieren entsprechender java.lang.Class-Objekte verantwortlich. Sobald eine Klasse in die JVM geladen wird, wird sie nicht erneut geladen.
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.
Wenn die JVM ausgeführt wird, werden drei ClassLoader generiert, nämlich BootstrapClassLoader (Stammklassenlader), ExtClassLoader (erweiterter Klassenlader) und AppClassLoader (Systemklassenlader). Die UML-Struktur ist wie folgt:
Unter anderem ist BootstrapClassLoader für das Laden der Kernklassenbibliothek von JRE verantwortlich. Es ist keine Unterklasse von ClassLoader und wird daher in Java nicht angezeigt. Wenn es über die Methode getParent() seiner Unterklasse abgerufen wird zurückgegeben werden. 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 im JRE-Erweiterungsverzeichnis ext verantwortlich, und AppClassLoader ist für das Laden des Klassenpakets unter dem Classpath-Pfad verantwortlich.
Der Test läuft wie folgt ab:
Kopieren Sie den Codecode wie folgt:
Paket com.stopTalking.crazy;
öffentliche Klasse TestClassLoader {
public static void main(String[] args) {
// Den Klassenlader des aktuellen Threads abrufen
ClassLoader Loader = Thread.currentThread().getContextClassLoader();
//Holen Sie sich den Klassenlader der Systemklasse
ClassLoader loader1 = System.class.getClassLoader();
// Holen Sie sich den Klassenlader Loader2 dieser Klasse TestClassLoader
ClassLoader loader2 = TestClassLoader.class.getClassLoader();
//Erhalte die übergeordnete Klasse von Loader2
ClassLoader Loader3 = Loader2.getParent();
//Erhalte die übergeordnete Klasse der übergeordneten Klasse von 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:
Kopieren Sie den Codecode wie folgt:
// Der von der aktuellen Thread-Klasse erhaltene Klassenlader ist AppClassLoader
sun.misc.Launcher$AppClassLoader@6b97fd
//Die Systemklasse wird vom Root-Loader geladen und kann in Java nicht aufgerufen werden, daher ist sie null
null
//Der Klassenlader dieser Klasse ist natürlich auch AppClassLoader
sun.misc.Launcher$AppClassLoader@6b97fd
sun.misc.Launcher$ExtClassLoader@1c78e57
null