Java-ClassLoader-delegation-Modell?
Beim Aufruf loadClass()
auf eine ClassLoader
, hat die ClassLoader
prüfen Sie zuerst, ob die Klasse geladen wurde, oder macht es sofort delegieren, diese Prüfung zu seinen Eltern ClassLoader
?
Java-API sagt:
Wenn das erforderlich ist, finden Sie eine Klasse oder eine Ressource, eine ClassLoader-Instanz delegieren die Suche für die Klasse oder Ressource, die zu Ihrer parent class loader, bevor Sie versuchen, um die Klasse zu finden, oder die Ressource selbst.
Aber es gibt ein spezielles Kapitel über den class-loader in das Buch Java Reflection in Action, der sagt:
Class-loader fordert findLoadedClass um zu überprüfen, ob die Klasse bereits geladen. Wenn ein class loader nicht finden eine geladene Klasse, ruft loadClass auf den parent-class-loader.
Ist das so richtig?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einen richtigen class loader Umsetzung:
Die default-Implementierung von ClassLoader.loadClass ist so etwas wie:
Einige class-loader-Implementierungen wird die delegation an andere non-parent-class-loader (OSGi, zum Beispiel, die Delegierten zu einem Diagramm der Klasse Lader je nach Paket) und einige class-loader-Implementierungen Aussehen wird für die Klassen in einem lokalen classpath, bevor Sie delegieren.
In der Java API korrekt ist.
Aus der Java-Mechanismus Zum Laden Von Klassen -
Die beiden Aussagen sind nicht ganz ausschließen. Die Klasse besteht nur in der aktuellen ClassLoader Satz von geladenen Klassen, wenn der übergeordnete ClassLoader hatten zuvor nicht an die Klasse zu finden. So,
Die nicht verhindern, dass es den Kurzschluss, wenn es weiß, dass seine Eltern nicht finden können, die Klasse, aber es kann (wie es zuvor laden der Klasse)
Dies ist im Grunde, wie es funktioniert. Sie geben
Zu diesem Zeitpunkt der classloader wird entscheiden, ob
Foo()
geladen wurden, nämlich seine bits im Speicher/perm gen. Wenn es geladen wurde, verwenden Sie dann. Ansonsten delegieren Sie an die parent-class-loader zu beheben, die Klasse. Die bits dieser Klasse vom Datenträger gelesen werden dann in den Speicher geladen. Auf der nächstennew Foo()
, würde die Klasse nun im Arbeitsspeicher gefunden/geladen.Übereinstimmen mit Sri ' s Antwort, es wird immer wieder an die Eltern und die api ist richtig. Wenn Sie spielen mit zum laden von Klassen, das sind die Dinge ein wenig schwierig, richtig zu machen, oder um die Effekte, die Sie nach sind. Ich würde vorschlagen, startet die jvm mit einer minimalen classpath, und lädt dann alle Klassen mit Ihren benutzerdefinierten classloader, der einfachste Weg, dies zu tun, ist die Verwendung einer URLClassloader oder ein zusammengesetztes Objekt umschließen einen URLClassloader, so würden Sie in der Lage sein zu verfolgen, welche Klassen geladen werden und wenn.
Auch zu Bedenken, dass eine Klasse Ein geladen, die von classloader C != die Klasse A geladen classloader C, wenn C und D sind nicht Teil der selben classloader als parent-child-Hierarchie.
Gibt es noch eine andere Sache, sollte erwähnt werden in diesem Zusammenhang. Die API-doc sagt:
Bedeutung, dass Netzwerke von verweisen auf Klassen geladen werden, die von den gleichen class loader.