© Excellent backgrounds/Shutterstock.com
Kolumne: Java-Trickkiste

Class Loading Reloaded


In Ausgabe 5.2015 habe ich über Class Loading geschrieben. Darauf ist von mehreren Seiten die Bitte gekommen, das Thema zu vertiefen. Das mache ich gern und blicke dabei hinter die Kulissen einiger Frameworks.

Standardablauf

Der Ablauf beim Laden von Klassen ist in der abstrakten Klasse java.lang.ClassLoader festgelegt. Alle konkreten ClassLoader-Implementierungen müssen von ihr erben. Sie implementiert das Standardverhalten, das eine ganze Reihe von Möglichkeiten zum Customizing vorsieht.

Zunächst ruft die Methode loadClass() die JVM auf. Das geschieht immer dann, wenn sie eine Klasse benötigt. Listing 1 zeigt ihren vereinfachten Quelltext aus den JDK-Sourcen.

Listing 1

private final ClassLoader parent; ... Class<?> loadClass (String name, boolean resolve) throws ClassNotFoundException { synchronized (...) { Class<?> c = findLoadedClass (name); if (c == null) { try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClass(name); } } catch (ClassNotFoundException e) { } if (c == null) { c = findClass (name); } } if (resolve) { resolveClass (c); } return c; } } protected native final Class<?> findLoadedClass(String name); private native Class<?> findBootstrapClass(String name); protected native final void resolveClass(Class<?> c); protected Class<?> findClass(String name) throws ClassNotFoundException { throw new ClassNotFoundException(name); } ...

Ganz außen in der Methode steht ein synchronized-Block. Er schützt den ClassLoader vor nebenläufigen Zugriffen. Die Details sehen wir uns weiter unten an.

Zum Laden der Klasse sucht der Code der Reihe nach an drei Stellen. Als Erstes fragt er mit einem Aufruf der native-Methode findLoadedClass() nach, ob dieser ClassLoader die Klasse schon einmal geladen hat. Dieses Caching beschleunigt Programme extrem und stellt sicher, dass es jede Klasse nur einmal je ClassLoader gibt. Wenn die Klasse noch nicht im Cache liegt, fragt er bei seinem Parent-ClassLoader oder dem System-ClassLoader nach. Führt auch das nicht zum Ziel, ruft er schließlich findClass() auf. So versucht der ClassLoader, die angefragte Klasse bereitzustellen. Diese Methode wirft per Default immer eine ClassNotFoundException, und ein konkreter ClassLoader muss diese implementieren – z. B. so, dass sie Code aus einer JAR-Datei lädt.

Der letzte Schritt beim Laden einer Klasse ist der optionale Aufruf von resolveClass(). Diese Methode lädt alle referenzierten Klassen nach, beispielsweise die Basisklasse, Rückgabetypen von...

Neugierig geworden?

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang