En quelques phrases simples, qu'est-ce qu'un Java ClassLoader, quand est-il utilisé et pourquoi?
OK, j'ai lu un article du wiki. ClassLoader charge des classes. D'ACCORD. Donc, si j'inclus les fichiers jar et les importe, un ClassLoader fait le travail.
Pourquoi devrais-je m'embêter avec ce ClassLoader? Je ne l'ai jamais utilisé et je ne savais pas qu'il existait.
La question est de savoir pourquoi la classe ClassLoader existe. Et aussi, comment l'utilisez-vous dans la pratique? (Les cas existent, je sais.)
Tiré de ce Nice tutorial de Sun:
Les applications écrites dans des langages de programmation compilés statiquement, tels que C et C++, sont compilées dans des instructions natives, spécifiques à la machine, puis enregistrées sous un fichier exécutable. Le processus de combinaison du code dans un code natif exécutable est appelé liaison - la fusion d'un code compilé séparément avec du code de bibliothèque partagée pour créer une application exécutable. Ceci est différent dans les langages de programmation compilés dynamiquement tels que Java. En Java, les fichiers .class générés par le compilateur Java restent tels quels jusqu'à leur chargement dans la machine virtuelle Java (JVM). En d'autres termes, le processus de liaison est exécuté par la machine virtuelle au moment de l'exécution. Les classes sont chargées dans la machine virtuelle Java "au besoin". Et lorsqu'une classe chargée dépend d'une autre classe, cette classe est également chargée.
Quand une application Java est lancée, la première classe à exécuter (ou le point d'entrée dans l'application) est celle qui utilise la méthode void statique publique appelée main (). Cette classe a généralement des références à d'autres classes et toutes les tentatives de chargement des classes référencées sont effectuées par le chargeur de classes.
Pour avoir une idée de ce chargement de classe récursif ainsi que de l'idée de chargement de classe en général, considérons la classe simple suivante:
public class HelloApp {
public static void main(String argv[]) {
System.out.println("Aloha! Hello and Bye");
}
}
Si vous exécutez cette classe en spécifiant l'option de ligne de commande -verbose: class afin d'afficher les classes en cours de chargement, vous obtiendrez une sortie qui se présente comme suit. Notez qu'il ne s'agit que d'une sortie partielle, car la liste est trop longue pour être affichée ici.
prmpt>Java -verbose:class HelloApp
[Opened C:\Program Files\Java\jre1.5.0\lib\rt.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jsse.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jce.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\charsets.jar]
[Loaded Java.lang.Object from shared objects file]
[Loaded Java.io.Serializable from shared objects file]
[Loaded Java.lang.Comparable from shared objects file]
[Loaded Java.lang.CharSequence from shared objects file]
[Loaded Java.lang.String from shared objects file]
[Loaded Java.lang.reflect.GenericDeclaration from shared objects file]
[Loaded Java.lang.reflect.Type from shared objects file]
[Loaded Java.lang.reflect.AnnotatedElement from shared objects file]
[Loaded Java.lang.Class from shared objects file]
[Loaded Java.lang.Cloneable from shared objects file]
[Loaded Java.lang.ClassLoader from shared objects file]
[Loaded Java.lang.System from shared objects file]
[Loaded Java.lang.Throwable from shared objects file]
.
.
.
[Loaded Java.security.BasicPermissionCollection from shared objects file]
[Loaded Java.security.Principal from shared objects file]
[Loaded Java.security.cert.Certificate from shared objects file]
[Loaded HelloApp from file:/C:/classes/]
Aloha! Hello and Bye
[Loaded Java.lang.Shutdown from shared objects file]
[Loaded Java.lang.Shutdown$Lock from shared objects file]
Comme vous pouvez le constater, les classes d'exécution Java requises par la classe d'application (HelloApp) sont chargées en premier.
Le langage de programmation Java continue d'évoluer pour faciliter la vie des développeurs d'applications au quotidien. Cela se fait en fournissant des API qui vous simplifient la vie en vous permettant de vous concentrer sur la logique métier plutôt que sur les détails de mise en œuvre des mécanismes fondamentaux. Cela est évident dans le récent changement de J2SE 1.5 à J2SE 5.0 afin de refléter la maturité de la plate-forme Java.
À partir de JDK 1.2, un chargeur de classe bootstrap intégré à la machine virtuelle Java est chargé de charger les classes du moteur d'exécution Java. Ce chargeur de classes ne charge que les classes trouvées dans le chemin de classe d'amorçage et, comme il s'agit de classes approuvées, le processus de validation n'est pas exécuté comme pour les classes non approuvées. Outre le chargeur de classe bootstrap, la machine virtuelle Java dispose d'un chargeur de classe d'extension chargé de charger les classes à partir d'API d'extension standard et d'un chargeur de classe système qui charge les classes à partir d'un chemin de classe général ainsi que vos classes d'application.
Puisqu'il y a plus d'un chargeur de classes, ils sont représentés dans un arbre dont la racine est le chargeur de classe bootstrap. Chaque chargeur de classe a une référence à son chargeur de classe parent. Lorsqu'un chargeur de classe est invité à charger une classe, il consulte son chargeur de classe parent avant de tenter de charger l'élément lui-même. Le parent à son tour consulte son parent, et ainsi de suite. C'est donc seulement après que tous les chargeurs de classes ancêtres ne peuvent pas trouver la classe que le chargeur de classes actuel est impliqué. En d'autres termes, un modèle de délégation est utilisé.
Java.lang.ClassLoader
Est une classe abstraite pouvant être sous-classée par les applications devant étendre la manière dont la JVM charge les classes de manière dynamique. Les constructeurs dans Java.lang.ClassLoader
(Et ses sous-classes) vous permettent de spécifier un parent lorsque vous instanciez un nouveau chargeur de classes. Si vous ne spécifiez pas explicitement un parent, le chargeur de classes système de la machine virtuelle sera attribué en tant que parent par défaut. En d'autres termes, la classe ClassLoader utilise un modèle de délégation pour rechercher des classes et des ressources. Par conséquent, chaque instance de ClassLoader est associée à un chargeur de classe parent. Ainsi, lorsqu'elle est invitée à rechercher une classe ou des ressources, la tâche est déléguée à son chargeur de classe parent avant toute tentative de recherche de la classe ou de la ressource elle-même. La méthode loadClass()
du ClassLoader effectue les tâches suivantes, dans l'ordre, lorsqu'elle est appelée pour charger une classe:
Si une classe a déjà été chargée, elle le renvoie. Sinon, il délègue la recherche de la nouvelle classe au chargeur de classes parent. Si le chargeur de classe parent ne trouve pas la classe, loadClass()
appelle la méthode findClass()
pour rechercher et charger la classe. La méthode finalClass()
recherche la classe dans le chargeur de classes en cours si celle-ci n'a pas été trouvée par le chargeur de classes parent.
Il y a plus dans l'article original, qui vous montre également comment implémenter vos propres chargeurs de classe de réseau, ce qui répond à votre question de savoir pourquoi (et comment). Voir aussi le docs de l'API .
La plupart des développeurs Java n’auront jamais besoin d’utiliser explicitement des chargeurs de classes (sauf pour charger des ressources afin qu’elles fonctionnent encore lorsqu'elles sont regroupées dans des JAR), et encore moins d’écrire leurs propres ressources.
Les ClassLoaders sont utilisés dans les grands systèmes et les applications serveur pour des tâches telles que:
La question est "Pourquoi devrait-on déranger cette classe ClassLoader existe"?
Eh bien, la plupart du temps pour que vous puissiez réparer les problèmes s’ils ne fonctionnent pas bien :-).
C'est vrai, tant que vous écrivez simplement une application, la compilez dans un JAR et incluez peut-être quelques JAR de bibliothèque supplémentaires, vous n'avez pas besoin de connaître les chargeurs de classes, cela fonctionnera.
Néanmoins, il est utile d’en savoir un peu plus sur les chargeurs de classes et le chargement de classes pour mieux comprendre ce qui se passe dans les coulisses. Par exemple, les "initialiseurs statiques" seront exécutés lors du chargement d'une classe. Par conséquent, pour savoir quand ils seront exécutés, vous devez savoir comment le chargeur de classes décide à quel moment les charger.
aussi .. comment l'utilisez-vous dans la pratique?
Pour les cas simples, vous n'en avez pas besoin. Toutefois, si vous devez charger le code de manière dynamique au moment de l'exécution avec un contrôle explicite d'où il provient (par exemple, chargement sur un réseau, chargement de plugins non disponibles à la compilation, etc.), vous devrez peut-être en faire plus. Ensuite, vous pouvez par exemple écrivez votre propre chargeur de classe. Voir les autres réponses pour les liens.
ClassLoader
in Java est une classe utilisée pour charger des fichiers de classe en Java. Java est compilé dans le fichier de classe par javac
Le compilateur et la machine virtuelle Java exécutent le programme Java) en exécutant des codes d'octet écrits dans le fichier de classe.
ClassLoader est responsable du chargement des fichiers de classe à partir du système de fichiers, du réseau ou de toute autre source. Trois chargeurs de classe par défaut utilisés en Java sont Bootstrap , Extension et Système ou application chargeur de classe.
## Interaction du chargeur de classe avec la machine virtuelle Java
Les chargeurs de classes sont un composant fonctionnel de la machine virtuelle Java, qui charge les données de classe à partir du fichier '.class' ou du réseau dans la zone de méthode de Heap.
Cela ressemble à une partie intégrante de la machine virtuelle Java, mais en tant que fin Java pourquoi devrais-je m'inquiéter? Voici pourquoi:
Chaque chargeur de classes a son propre espace de noms et les classes appelées par un chargeur de classes particulier sont insérées dans son espace de noms.
Les classes appelées par deux chargeurs de classes différents n'auront aucune visibilité l'une sur l'autre, ce qui renforcera la sécurité.
Le mécanisme de délégation des enfants parents du chargeur de classes assure Java) les classes de l'API ne pourront jamais être piratées par du code non autorisé.
Pour plus de détails, regardez ici
Lorsque vous demandez pourquoi la classe ClassLoader existe, la raison en est assez simple: c'est la classe responsable de la recherche et du chargement de fichiers de classe au moment de l'exécution .
Élaborons cela.
Dans la JVM, chaque classe est chargée par une instance de Java.lang.ClassLoader
. Chaque fois qu’une nouvelle machine virtuelle Java est lancée de votre part, le programme Java qui lance Java <classname>
commande, la première étape consiste à charger toutes les classes de clés en mémoire nécessaires au bon fonctionnement, comme Java.lang.Object
et d’autres classes d’exécution (rt.jar
).
ClassLoader se compose de trois parties:
Le BootstrapClassLoader
est chargé de rendre ces classes disponibles, c'est-à-dire de les charger en mémoire.
La tâche suivante consiste à charger des bibliothèques/JAR externes dans la mémoire pour un bon fonctionnement de l'application. Le ExtClassLoader
est responsable de cette tâche. Ce chargeur de classe est responsable du chargement de tous les fichiers .jar mentionnés dans le chemin Java.ext.dirs.
Le troisième et le principal chargeur de classe important est le AppClassLoader
. Le chargeur de classe de l’application est chargé du chargement des fichiers de classe mentionnés dans la propriété système Java.class.path.
Il est également important de noter que les implémentations ClassLoader par défaut peuvent être remplacées, ce qui vous permet de personnaliser la machine virtuelle de manière utile et intéressante, vous permettant ainsi de redéfinir complètement la manière dont les fichiers de classe sont importés dans le système.
Consultez-le pour en savoir plus sur Java Class Loader .
Les chargeurs de classe sont hiérarchiques. Les classes sont introduites dans la machine virtuelle Java car elles sont référencées par leur nom dans une classe déjà en cours d'exécution dans la machine virtuelle Java.
Comment est chargée la toute première classe?
La toute première classe est chargée à l'aide de la méthode static main()
déclarée dans votre classe. Toutes les classes chargées ultérieurement sont chargées par les classes déjà chargées et en cours d'exécution.
Un chargeur de classe crée un espace de noms. Tous [~ # ~] jvm [~ # ~] incluent au moins un chargeur de classe intégré à la machine virtuelle appelée primordial (ou bootstrap) chargeur de classe. C’est une chose, et nous allons examiner les chargeurs de classes non primordiaux. La machine virtuelle Java comporte des crochets permettant aux chargeurs de classe définis par l'utilisateur d'être utilisés à la place du chargeur de classe primordial. Voici les chargeurs de classe créés par la machine virtuelle Java.
Bootstrap (primordial) Ce chargeur de classe n'est pas rechargeable. Charge les classes internes JDK, les packages Java. * (Charge généralement rt.jar et i18n.jar). Extesions Ce chargeur de classe n'est pas rechargeable. Charge les fichiers JAR à partir du répertoire des extensions JDK (généralement lib/ext de JRE). Système Ce chargeur de classe n'est pas rechargeable. Charge les classes à partir du chemin de classe du système.