Was ist ein class loader?

Ein class loader dient dazu, zur Laufzeit Klassen und Ressourcen zu laden.

Selbst relativ einfache Programme bestehen aus mehreren, teils unabhängigen Anteilen, die jedoch innerhalb des Programms funktional zusammenarbeiten müssen. Die Verbindung dieser Teile geschieht durch das sog. Linken, einer binären Verknüpfung der Einzelteile zu einer Ausführungseinheit. Man unterscheidet statisches und dynamisches Linken. Bei statisch gelinkten Sprachen wie z.B. C/C++ geschieht das Linken i.A. im Laufe des Kompilierens in Maschinencode.

Java ist dynamisch gelinkt: Ein Java-Programm nutzt oft eine ganze Reihe an Dateien der Java-Bibliothek, Extensionen, vom Programmierer definierten class-Dateien und Ressourcen wie z.B. Bildern. Der Bytecode dieser Daten wird erst dann in die JVM geladen, wenn er tatsächlich während der Ausführung des Programms benötigt wird.
Eine Vorstellung von den zur Laufzeit geladenen Programmteilen erhält man, wenn man ein Programm mit dem Kommandozeilen-Parameter -verbose:class aufruft.

$ java -verbose:class HalloWelt

Für das Laden dieser Daten sind class loader verantwortlich, von denen Java drei unterschiedliche Typen kennt, die hierarchisch miteinander verknüpft sind. Darüber hinaus ist es möglich, eigene class loader zu schreiben, die sich von der Klasse ClassLoader ableiten.

Auf oberster Ebene befindet sich der bootstrap class loader. Er ist für das Laden der Core-Klassen der Java Laufzeit-Umgebung verantwortlich, im Wesentlichen denjenigen, die sich in rt.jar befinden. Auf der Abhängigkeitsebene darunter verfügt die JVM über einen extension class loader, der für das Laden von Erweiterungen zuständig ist, die sich in den Erweiterungs-Verzeichnissen der JRE-Installation befinden.
Als dritter existiert ein system class loader, auch application class loader genannt, der für die programmeigenen Klassen und Ressourcen zuständig ist und diese vom CLASSPATH lädt.

Bis auf den an oberster Ebene stehenden bootstrap class loader besitzen alle Referenzen auf den jeweils in der Hierarchie nach oben folgenden, sodass eine Anfrage zum Laden einer Klasse weiterdelegiert werden kann und ein class loader in diesem Fall weiß, welche Klassen seine Eltern-class loader geladen haben, umgekehrt jedoch nicht. Beim Ladevorgang geschieht Folgendes:
Soll z.B. eine selbst definierte Klasse Test.class aus dem CLASSPATH geladen werden, so delegiert der hierzu angesprochene application class loader die Anfrage an den extension class loader und dieser wiederum an den bootstrap class loader. Dieser versucht vergeblich die Klasse in rt.jar zu finden und reicht die Anfrage an den extension class loader wieder zurück, der die Klasse ebenfalls nicht in den Erweiterungs-Verzeichnissen findet. Schließlich wird der application class loader die Klasse finden und wunschgemäß aus dem Klassenpfad laden.

Der aktive class loader wird anschließend als defining class loader mit dem geladenden Typ von der VM registriert.

Quellen
  1. https://javarevisited.blogspot.de/2012/12/how-classloader-works-in-java.html
  2. https://www.ibm.com/developerworks/java/tutorials/j-classloader/j-classloader.html
  3. https://www.oracle.com/technetwork/articles/javase/classloaders-140370.html
  4. https://www.developer.com/java/other/article.php/10936_2248831_2/Java-Class-Loading-The-Basics.htm

Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.