Warum einen Klassenlader verwenden?
In der Java -Sprache wird die Klassenbelastung während des Programmbetriebs abgeschlossen. Diese Strategie erhöht zwar bei der Klassenbelastung leicht die Leistungsaufwand, bietet Java -Anwendungen mit einem hohen Grad an Flexibilität. Zum Beispiel:
1. Schreiben Sie eine interface-orientierte Anwendung und können Sie warten, bis sie ausgeführt wird, bevor Sie ihre Implementierungsunterklasse angeben.
2. Benutzer können einen Klassenlader anpassen, sodass das Programm einen Binärstrom aus dem Netzwerk oder an anderen Stellen als Teil des Programmcodes zur Laufzeit laden kann. (Dies ist die Grundlage für Android-Plug-In, dynamische Installation und Aktualisierung des APK)
Warum den gesamten Prozess der Klassenbelastung studieren?
Klassenbeladungsmechanismus
Das JVM lädt die Klassendatei in den Speicher, überprüft, analysiert und initialisiert die Daten und bildet schließlich den gesamten Prozess des Java -Typs, den die JVM direkt verwenden kann.
laden
Laden Sie den Bytecode -Inhalt der Klassendatei in den Speicher und konvertieren Sie die statischen Daten in eine Laufzeitdatenstruktur im Methodenbereich und generieren Sie ein java.lang.Class -Objekt, das diese Klasse im Heap als Zugriffsportal für die Klassendaten der Methodenbereich darstellt. Dieser Prozess erfordert die Teilnahme des Klassenladers.
Link
Der Prozess der Kombination des Binärcode der Java -Klasse in den laufenden Zustand des JVM
Initialisierung
<clinit>() . Die Methode der Klassenkonstruktor <clinit>() wird vom Compiler generiert, der automatisch die Zuordnungsaktionen aller Klassenvariablen in der Klasse und die Verschmelzung von Aussagen im statischen Anweisungsblock (statischer Block) sammelt.<clinit>() in einer Umgebung mit mehreren Threaden korrekt gesperrt und synchronisiert ist.Beispiel 1:
public class Demo01 {public static void main (String [] args) {a = new a (); System.out.println (A.Width); }} Klasse A {public static int width = 100; // statische Variable, statisches Feld statisch {System.out.println ("statische Initialisierungsklasse A"); Breite = 300; } public a () {System.out.println ("ein Objekt der Klasse A erstellen"); }}analysieren:
veranschaulichen:
Es gibt Stapel, Haufen (Orte erstellte Objekte) und Methodenbereiche im Speicher (eigentlich ein spezieller Heap)
1. Wenn das JVM Demo01 lädt, bilden Sie zunächst die statischen Daten (Klassenvariablen, Klassenmethoden, Code ...) im Methodenbereich. Gleichzeitig wird ein java.lang.Class -Objekt (reflektierendes Objekt) im Haufen gebildet, das die Demo01 -Klasse darstellt. Durch das Objekt kann auf die Klassenbinärstruktur zugegriffen werden. Laden Sie dann die Informationen zur Variablenklasse A und bilden Sie auch ein Objekt A im Haufen, was die Klasse A darstellt.
2. Wenn die Hauptmethode ausgeführt wird, wird im Stapel der Hauptmethodenstapelrahmen gebildet, und eine Methode entspricht einem Stapelrahmen. Wenn die Hauptmethode andere Methoden aufruft, drückt sie nacheinander im Stapel. Es gibt eine lokale Variable A vom Typ A in der Hauptmethode. Zu Beginn ist der Wert von a null. Der Konstruktor der Klasse A wird durch neu aufgerufen. Die a () -Methode wird im Stapel erzeugt und das A -Objekt im Haufen erzeugt. Dann wird die A -Objektadresse an einen im Stapel gezahlt. Zu diesem Zeitpunkt hat A die A -Objektadresse.
3. Wenn A.width aufgerufen wird, werden die Methodenbereichsdaten aufgerufen.
Wenn eine Klasse durch Referenz geladen wird, wird die Klasse nur einmal geladen
Aktive Referenz der Klasse (Klasseninitialisierung wird definitiv auftreten)
java.lang.reflect , um Reflexionsaufrufe an die Klasse zu tätigen Passiver Hinweis auf die Klasse (Klasseninitialisierung tritt nicht auf)
Beispiel 2:
public class Demo01 {static {System.out.println ("statische Initialisierung Demo01"); } public static void main (String [] args) löst eine Ausnahme aus {System.out.println ("Demo01 -Hauptmethode!"); System.out.println (System.getProperty ("java.class.Path")); // aktive Referenz // new a (); // system.out.println (A.Width); // class.forname ("com.sinosoft.test.a"); // Passive Referenz // System.out.println (a.max); // a [] as = new a [10]; System.out.println (B.Width); // Klasse B wird nicht geladen}} Klasse B erweitert a {static {System.out.println ("statische Initialisierung B"); }} Klasse A erweitert a_father {public static int width = 100; // statische Variable, statisches Domänenfeld Öffentliche statische endgültige int max = 100; static {System.out.println ("statische Initialisierungsklasse A"); Breite = 300; } public a () {System.out.println ("ein Objekt der Klasse A erstellen"); }} class a_father erweitert das Objekt {static {System.out.println ("statische Initialisierung a_father"); }}Zusammenfassen
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Referenzwert für das Studium oder die Arbeit eines jeden hat. Wenn Sie Fragen haben, können Sie eine Nachricht zur Kommunikation überlassen. Vielen Dank für Ihre Unterstützung bei Wulin.com.