15.4 Klassenlader
In Java ist eine Kaskade von unterschiedlichen Klassenladern für das Laden von Klassen verantwortlich. Bei Java arbeiten mehrere Klassenlader in einer Kette zusammen:
An erster Stelle steht der Klassenlader für alle »Kern«-Klassen, der Bootstrap-Klassenlader. Er lädt zentrale Typen wie Object und String aus der Laufzeitbibliothek. Findet er eine gewünschte Klasse nicht, geht die Anfrage weiter.
Der Plattform-Klassenlader (vor Java 8 »extension class loader« genannt) lädt weitere Klassen aus der Distribution, die keine Kernklassen sind.
Applikations-Klassenlader (auch System-Klassenlader): Wenn eine Klasse auch vom Plattform-Klassenlader nicht gefunden wurde, folgt die Suche über den benutzerdefinierten Klassen- bzw. Modulpfad.
Aus Sicherheitsgründen beginnt der Klassenlader bei einer neuen Klasse immer mit dem Bootstrap-Klassenlader und reicht dann die Anfrage weiter, wenn er selbst die Klasse nicht laden konnte. Dazu sind die Klassenlader miteinander verbunden. Jeder Klassenlader L hat dazu einen Vater-Klassenlader V. Erst darf der Vater versuchen, die Klassen zu laden. Kann er es nicht, gibt er die Arbeit an L ab.
Hinter dem letzten Klassenlader können wir einen eigenen benutzerdefinierten Klassenlader installieren. Auch dieser wird einen Vater haben, den üblicherweise der Applikations-Klassenlader verkörpert.
Abfragen des Klassenpfades
Ob der eigene Klassenpfad überhaupt gesetzt ist, ermittelt ein einfaches echo %CLASSPATH% (Windows) bzw. echo $CLASSPATH (Unix).
Zur Laufzeit steht der normale Klassenpfad in der System-Property java.class.path.
Eigenschaft | Beispielbelegung |
---|---|
java.class.path | C:\Users\Christian\Insel\programme\2_17_Reflection_Annotationen |
[»] Hinweis
Wird die JVM über java -jar aufgerufen, beachtet sie nur Klassen in dem genannten JAR und ignoriert den Klassenpfad.
15.4.1 Die Klasse java.lang.ClassLoader
Jeder Klassenlader in Java ist vom Typ java.lang.ClassLoader. Die Methode loadClass(…) erwartet einen sogenannten binären Namen, der an den voll qualifizierten Klassennamen erinnert.
abstract class java.lang.ClassLoader
protected Class<?> loadClass(String name, boolean resolve)
Lädt die Klasse und bindet sie mit resolveClass(…) ein, wenn resolve gleich true ist.Class<?> loadClass(String name)
Die öffentliche Methode ruft loadClass(name, false) auf, was bedeutet, dass die Klasse nicht standardmäßig angemeldet (gelinkt) wird. Beide Methoden können eine ClassNotFoundException auslösen.
Die geschützte Methode führt anschließend drei Schritte durch:
Wird loadClass(…) auf einer Klasse aufgerufen, die dieser Klassenlader schon eingelesen hat, so kehrt die Methode mit dieser gecachten Klasse zurück.
Ist die Klasse nicht gespeichert, darf zuerst der Vater (Parent Class Loader) versuchen, die Klasse zu laden.
Findet der Vater die Klasse nicht, so darf jetzt der Klassenlader selbst mit findClass(…) versuchen, die Klasse zu beziehen.
Eigene Klassenlader überschreiben in der Regel die Methode findClass(…), um nach einem bestimmten Schema zu suchen, etwa nach Klassen aus der Datenbank. In diesen Stufen ist es auch möglich, höher stehende Klassenlader zu umgehen, was beispielsweise bei Servlets Anwendung findet.