Première partie. Invite Dois-je lire cet article ?
Le chargeur de classes Java est crucial pour le fonctionnement du système Java, mais nous l'ignorons souvent. Le chargeur de classes Java charge les classes au moment de l'exécution en les recherchant et en les chargeant. Les chargeurs de classes personnalisés peuvent changer complètement la façon dont les classes sont chargées, en personnalisant votre machine virtuelle Java comme vous le souhaitez. Cet article présente brièvement le chargeur de classe Java, puis l'illustre à travers un exemple de construction d'un chargeur de classe personnalisé. Ce chargeur de classe compilera automatiquement le code avant de charger la classe. Vous apprendrez ce que fait réellement un chargeur de classe et comment créer le vôtre. Tant que vous possédez des connaissances de base en Java, savez comment créer, compiler et exécuter un programme Java en ligne de commande et quelques concepts de base des fichiers de classe Java, vous pouvez comprendre le contenu de cet article. Après avoir lu cet article, vous devriez être capable de :
* Développez les fonctions de la machine virtuelle Java
* Créer un chargeur de classe personnalisé
* Comment intégrer un chargeur de classes personnalisé dans votre application
* Modifiez votre chargeur de classe pour qu'il soit compatible avec Java 2
Partie 2. Introduction Qu'est-ce qu'un chargeur de classe ?
La différence entre Java et les autres langages est que Java s'exécute sur la machine virtuelle Java (JVM). Cela signifie que le code compilé est enregistré dans un format indépendant de la plate-forme, plutôt que dans un format qui s'exécute sur une machine spécifique. Ce format présente de nombreuses différences importantes par rapport au format de code exécutable traditionnel. Plus précisément, contrairement à un programme C ou C++, un programme Java n'est pas un fichier exécutable indépendant, mais se compose de nombreux fichiers de classe distincts, chaque fichier de classe correspondant à une classe Java. De plus, ces fichiers de classe ne sont pas chargés en mémoire immédiatement, mais sont chargés lorsque le programme en a besoin. Un chargeur de classes est un outil utilisé dans la machine virtuelle Java pour charger des classes en mémoire. De plus, le chargeur de classes Java est également implémenté en Java. De cette façon, vous pouvez facilement créer votre propre chargeur de classes sans avoir une compréhension approfondie de la machine virtuelle Java.
Pourquoi créer un chargeur de classe ?
Maintenant que Java Virtual Gold dispose déjà d’un chargeur de classes, devons-nous en créer d’autres nous-mêmes ? Bonne question ? Le chargeur de classes par défaut sait uniquement comment charger les classes à partir du système local. Lorsque votre programme est entièrement compilé de manière native, le chargeur de classes par défaut fonctionne généralement bien. Mais l’un des aspects les plus intéressants de Java réside dans la facilité avec laquelle il est possible de charger des classes depuis le réseau plutôt que simplement localement.
Par exemple, un navigateur peut charger des classes via un chargeur de classes personnalisé. Il existe également de nombreuses façons de charger des cours. L'une des choses les plus intéressantes à propos de Java est que vous pouvez le personnaliser simplement à partir d'un emplacement local ou réseau :
* Vérifiez automatiquement les signatures numériques avant d'exécuter du code non fiable
* Décryptez le code en fonction du mot de passe fourni par l'utilisateur
* Créez dynamiquement des classes en fonction des besoins des utilisateurs. Tout ce qui vous intéresse peut être facilement intégré à votre application sous forme de bytecode. Exemples de chargeurs de classes personnalisés si vous avez utilisé l'appletviewer JDK (Java Software Development Kit) (petit navigateur d'applications) ou autre.
Pour les navigateurs Java intégrés, vous utilisez déjà un chargeur de classe personnalisé. Lorsque Sun a lancé le langage Java pour la première fois, l'une des choses les plus passionnantes était d'observer comment Java exécutait le code téléchargé à partir d'un site Web distant. Exécuter depuis un site distant via HTTP
Le bytecode transmis par la connexion P semble un peu bizarre. Cela fonctionne car Java a la capacité d'installer des chargeurs de classes personnalisés. Le navigateur d'applets contient un chargeur de classe. Ce chargeur de classe ne trouve pas les classes Java localement, mais accède au serveur distant, charge le fichier de bytecode d'origine via HTTP, puis le convertit en classe Java dans la machine virtuelle Java. Bien sûr, les chargeurs de classes font beaucoup d'autres choses : ils bloquent les classes Java non sécurisées et empêchent les différentes applets sur différentes pages d'interférer les unes avec les autres. Echidna, un package écrit par Luke Gorrie, est un package logiciel Java ouvert qui permet d'exécuter plusieurs applications Java en toute sécurité dans une machine virtuelle Java. Il évite les interférences entre les applications en utilisant un chargeur de classe personnalisé pour donner à chaque application une copie du fichier de classe.
Notre exemple de chargeur de classe Maintenant que nous savons comment fonctionne un chargeur de classe et comment définir notre propre chargeur de classe, nous créons un chargeur de classe personnalisé nommé CompilingClassLoader (CCL). CCL effectue le travail de compilation pour nous, nous n'avons donc pas à le compiler manuellement nous-mêmes. Cela équivaut fondamentalement à avoir un programme « make » qui s'intègre dans notre environnement d'exécution.
Remarque : Avant de passer à l'étape suivante, il est nécessaire de comprendre certains concepts connexes.
Le système a été grandement amélioré dans la version 1.2 du JDK (que nous appelons la plateforme Java 2). Cet article a été écrit sous JDK 1.0 et 1.1, mais tout fonctionnera dans les versions ultérieures. ClassLoader a également été amélioré en Java2.
Une introduction détaillée est fournie dans la cinquième partie.
Partie 3. Présentation de la structure de ClassLoader L'objectif fondamental d'un chargeur de classe est de répondre aux requêtes de classes Java. Lorsque la machine virtuelle Java a besoin d'une classe, elle donne un nom de classe au chargeur de classe, puis celui-ci essaie de renvoyer une instance de classe correspondante. Des chargeurs de classes personnalisés peuvent être créés en remplaçant les méthodes correspondantes à différentes étapes. Nous découvrirons ensuite certaines des principales méthodes du chargeur de classe. Vous comprendrez ce que font ces méthodes et comment elles fonctionnent lors du chargement de fichiers de classe. Vous saurez également quel code vous devez écrire lors de la création d'un chargeur de classe personnalisé. Dans la partie suivante, vous exploiterez ces connaissances et notre CompilingCl personnalisé
assLoader fonctionne ensemble.
MéthodeloadClass
ClassLoader.loadClass() est le point d'entrée de ClassLoader. La signature de la méthode est la suivante :
Classe loadClass (nom de chaîne, résolution booléenne) ;
Le nom du paramètre spécifie le nom complet de la classe (y compris le nom du package) requise par la machine virtuelle Java, telle que Foo ou java.lang.Object.
Le paramètre solve spécifie si la classe doit être résolue. Vous pouvez comprendre la résolution de la classe comme étant complètement prête à être exécutée. L'analyse n'est généralement pas requise. Si la machine virtuelle Java souhaite uniquement savoir si cette classe existe ou si elle souhaite connaître sa classe parent, l'analyse est totalement inutile. Dans Java 1.1 et ses versions précédentes, si vous souhaitez personnaliser le chargeur de classe, la méthode loadClass est la seule méthode qui doit être substituée dans la sous-classe.
(ClassLoader a changé en Java1.2 et a fourni la méthode findClass()).
méthodedefineClass
DefineClass est une méthode très mystérieuse dans ClassLoader. Cette méthode construit une instance de classe à partir d'un tableau d'octets. Ce tableau d'octets bruts contenant des données peut provenir du système de fichiers ou du réseau. DefineClass illustre la complexité, le mystère et la dépendance à la plate-forme de la machine virtuelle Java : il interprète le bytecode pour le transformer en structures de données d'exécution, vérifie la validité, et bien plus encore. Mais ne vous inquiétez pas, vous n’êtes pas obligé de faire quoi que ce soit de tout cela. En fait, vous ne pouvez pas du tout l'annuler,
Car la méthode est modifiée par le mot-clé final.
MéthodefindSystemClass
La méthode findSystemClass charge les fichiers du système local. Il recherche les fichiers de classe sur le système local et, s'il les trouve, appelle
DefinClass convertit le tableau d'octets d'origine en un objet de classe. Il s'agit du mécanisme par défaut permettant à la machine virtuelle Java de charger des classes lors de l'exécution d'applications Java. Pour les chargeurs de classes personnalisés, nous devons uniquement utiliser findSystemClass après un échec de chargement. La raison est simple : notre chargeur de classes est chargé d'effectuer certaines étapes du chargement des classes, mais pas de toutes les classes. Par exemple,
Même si notre chargeur de classes charge certaines classes depuis le site distant, de nombreuses classes de base doivent encore être chargées depuis le système local.
Ces classes ne nous concernent pas, nous laissons donc la machine virtuelle Java les charger de la manière par défaut : depuis le système local. C'est ce que fait findSystemClass. L'ensemble du processus est à peu près le suivant :
* La machine virtuelle Java demande à notre chargeur de classe personnalisé de charger la classe.
* Nous vérifions si le site distant possède la classe qui doit être chargée.
* S'il y en a, nous obtenons cette classe.
* Sinon, nous pensons que cette classe se trouve dans la bibliothèque de classes de base et appelons findSystemClass pour la charger depuis le système de fichiers.
Dans la plupart des chargeurs de classes personnalisés, vous devez d'abord appeler findSystemClass pour gagner du temps lors de la recherche à partir de la télécommande.
En fait, comme nous le verrons dans la section suivante, la machine virtuelle Java n'est autorisée à charger des classes depuis le système de fichiers local que lorsque nous sommes sûrs d'avoir automatiquement compilé notre code.
Méthode solveClass
Comme mentionné ci-dessus, les enregistrements de classe peuvent être divisés en chargement partiel (sans analyse) et chargement complet (y compris l'analyse). Lorsque nous créons un chargeur de classe personnalisé, nous devrons peut-être appeler solveClass.
MéthodefindLoadedClass
findLoadedClass implémente un cache : lorsque loadClass est requis pour charger une classe, vous pouvez d'abord appeler cette méthode pour voir si la classe a été chargée afin d'éviter de recharger une classe déjà chargée. Cette méthode doit être appelée en premier. Voyons comment ces méthodes sont organisées ensemble.
Notre exemple d’implémentation de loadClass effectue les étapes suivantes. (Nous ne spécifions pas de technologie spécifique pour obtenir le fichier de classe - il peut provenir du réseau, d'un package compressé ou compilé dynamiquement. Dans tous les cas, ce que nous obtenons est le fichier de bytecode original)
* Appelez findLoadedClass pour vérifier si cette classe a été chargée.
* S'il n'est pas chargé, nous obtenons le tableau d'octets d'origine d'une manière ou d'une autre.
* Si le tableau a été obtenu, appelez définirClass pour le convertir en objet de classe.
* Si le tableau d'octets d'origine ne peut pas être obtenu, appelez findSystemClass pour vérifier s'il peut être enregistré à partir du système de fichiers local.
* Si le paramètre solve est vrai, appelez solveClass pour résoudre l'objet de classe.
* Si la classe n'a pas été trouvée, lancez une ClassNotFoundException.
* Sinon, renvoyez cette classe.
Maintenant que nous avons une compréhension plus complète des connaissances pratiques des chargeurs de classes, nous pouvons créer un chargeur de classes personnalisé. Dans la section suivante, nous discuterons du CCL.
Partie 4. CompilationClassLoader
CCL nous montre la fonction du chargeur de classe. Le but de CCL est de permettre à notre code d'être automatiquement compilé et mis à jour. Voici comment cela fonctionne :
* Lorsqu'il y a une demande pour une classe, vérifiez d'abord si le fichier de classe existe dans le répertoire actuel et les sous-répertoires du disque.
* S'il n'y a pas de fichier de classe, mais qu'il existe un fichier de code source, appelez le compilateur Java pour compiler et générer le fichier de classe.
* Si le fichier de classe existe déjà, vérifiez si le fichier de classe est plus ancien que le fichier de code source. Si le fichier de classe est plus ancien que le fichier de code source, appelez le compilateur Java pour régénérer le fichier de classe.
* Si la compilation échoue ou si le fichier de classe ne peut pas être généré à partir du fichier source pour d'autres raisons, lancez l'exception ClassNotFou
ndException.
* Si vous n'avez pas encore obtenu cette classe, elle peut exister dans d'autres bibliothèques de classes. Appelez findSystemClass pour voir si elle peut être trouvée.
* S'il n'est pas trouvé, lancez ClassNotFoundException.
* Sinon, renvoyez cette classe.
Comment la compilation Java est-elle implémentée ?
Avant d'aller plus loin, nous devons comprendre le processus de compilation Java. Normalement, le compilateur Java compile uniquement les classes spécifiées. Il compilera également d'autres classes associées si les classes spécifiées l'exigent. CCL compilera les classes dont nous avons besoin pour compiler dans l'application une par une. Cependant, d'une manière générale, une fois que le compilateur a compilé la première classe,
CCL constatera que d'autres classes connexes requises ont effectivement été compilées. Pourquoi? Le compilateur Java utilise des règles similaires aux nôtres : si une classe n'existe pas ou si le fichier source a été mis à jour, la classe sera compilée. Le compilateur Java a fondamentalement une longueur d'avance sur CCL et la plupart du travail est effectué par le compilateur Java. Il semble que CCL compile ces classes.
Dans la plupart des cas, vous constaterez qu'il appelle le compilateur dans la classe de fonctions principale, et c'est tout : un simple appel suffit. Il existe cependant un cas particulier où ces classes ne sont pas compilées lors de leur première apparition. Si vous chargez une classe en fonction de son nom, à l'aide de la méthode Class.forName, le compilateur Java ne sait pas si la classe est nécessaire. dans ce cas,
Vous constatez que CCL appelle à nouveau le compilateur pour compiler la classe. Le code de la section 6 illustre ce processus.
Utilisation de CompilationClassLoader
Pour utiliser CCL, nous ne pouvons pas exécuter notre programme directement, il doit être exécuté d'une manière spéciale, comme ceci :
% java Foo arg1 arg2
Nous l'exécutons comme ceci :
% java CCLRun Foo arg1 arg2
CCLRun est un programme stub spécial qui crée CompilingClassLoader et l'utilise pour charger notre classe de fonctions principale. Cela garantit que l'intégralité du programme est chargée par CompilingClassLoader. CCLRun utilise Ja
L'API de réflexion va appelle la fonction principale de la classe de fonctions principale et transmet les paramètres à cette fonction. Pour en savoir plus, reportez-vous au code source de la partie 6.
Exécutons l'exemple pour démontrer comment fonctionne l'ensemble du processus.
Le programme principal est une classe appelée Foo, qui crée une instance de la classe Bar. Cette instance Bar crée à son tour une instance de la classe Baz, qui existe dans le package baz. Ceci vise à démontrer comment CCL charge les classes à partir des sous-packages. Bar charge également la classe Boo en fonction du nom de la classe
, cela est également fait par CCL. Toutes les classes sont chargées et prêtes à fonctionner. Utilisez le code source du chapitre 6 pour exécuter ce programme. Compilez CCLRun et CompilingClassLoader. Assurez-vous de ne pas compiler d'autres classes (Foo, Bar, Baz, un
nd Boo), sinon CCL ne fonctionnera pas.
% java CCLRun Foo arg1 arg2
CCL : Compilation de Foo.java...
foo !
barre ! arg1 arg2
baz! arg1 arg2
CCL : Compilation de Boo.java...
Huer!
Notez que le compilateur est appelé pour la première fois pour Foo.java, et que Bar et baz.Baz sont également compilés ensemble. Et comme Bouh
Lorsque le canal doit être chargé, CCL appelle à nouveau le compilateur pour le compiler.
Partie 5. Présentation des améliorations du chargeur de classe dans Java 2 Dans Java 1.2 et les versions ultérieures, le chargeur de classe a été considérablement amélioré. L'ancien code fonctionne toujours, mais le nouveau système facilite notre implémentation. Ce nouveau modèle est le modèle de délégation proxy, ce qui signifie que si le chargeur de classe ne trouve pas de classe, il demandera à son chargeur de classe parent de la trouver. Le chargeur de classes système est l'ancêtre de tous les chargeurs de classes. Le chargeur de classes système charge les classes par défaut, c'est-à-dire à partir du système de fichiers local. La substitution de la méthode loadClass essaie généralement plusieurs façons de charger la classe. Si vous écrivez beaucoup de chargeurs de classe, vous constaterez que vous apportez simplement quelques modifications à cette méthode compliquée, encore et encore. L'implémentation par défaut de loadClass dans Java 1.2 inclut la manière la plus courante de rechercher une classe, vous permettant de remplacer la méthode findClass et loadClass pour appeler la méthode findClass de manière appropriée. L'avantage est que vous n'avez pas besoin de remplacer loadClass, il vous suffit de remplacer findClass, ce qui réduit la charge de travail.
Nouvelle méthode : findClass
Cette méthode est appelée par l'implémentation par défaut de loadClass. Le but de findClass est d'inclure tout le code spécifique au chargeur de classe,
Il n'est pas nécessaire de répéter le code (par exemple, appeler le chargeur de classe système lorsque la méthode spécifiée échoue).
Nouvelle méthode : getSystemClassLoader
Que vous substituiez ou non les méthodes findClass et loadClass, la méthode getSystemClassLoader peut accéder directement au chargeur de classe système (plutôt qu'un accès indirect via findSystemClass).
Nouvelle méthode : getParent
Afin de déléguer la requête au chargeur de classe parent, le chargeur de classe parent de ce chargeur de classe peut être obtenu via cette méthode. Vous pouvez déléguer la requête au chargeur de classe parent lorsqu'une méthode spécifique dans un chargeur de classe personnalisé ne parvient pas à trouver la classe. Le chargeur de classe parent d'un chargeur de classe contient le code qui crée le chargeur de classe.
Partie 6. Code source
CompilationClassLoader.java
Voici le contenu du fichier CompilingClassLoader.java
importer java.io.* ;
/*
CompilingClassLoader compile dynamiquement les fichiers source Java. Il vérifie si le fichier .class existe et si le fichier .class est plus ancien que le fichier source.
*/
la classe publique CompilingClassLoader étend ClassLoader
{
//Spécifiez un nom de fichier, lisez l'intégralité du contenu du fichier à partir du disque et renvoyez un tableau d'octets.
private byte[] getBytes(String filename) lance IOException {
// Récupère la taille du fichier.
Fichier fichier = nouveau fichier (nom de fichier);
long len = fichier.longueur();
//Créez un tableau juste assez pour stocker le contenu du fichier.
octet brut[] = nouvel octet[(int)len];
//Ouvrir le fichier
FileInputStream fin = new FileInputStream( fichier );
// Lire tout le contenu. S'il ne peut pas être lu, une erreur s'est produite.
int r = fin.read(raw);
si (r != len)
throw new IOException( "Impossible de tout lire, "+r+" != "+len );
// N'oubliez pas de fermer le fichier.
fin.close();
// Renvoie ce tableau.
retourner brut ;
}
// Génère un processus pour compiler le fichier source Java spécifié et spécifie les paramètres du fichier Si la compilation réussit, renvoie true, sinon,
// Renvoie faux.
la compilation booléenne privée (String javaFile) lance IOException {
//Afficher la progression actuelle
System.out.println( "CCL : Compilation de "+javaFile+"..." );
//Démarre le compilateur
Processus p = Runtime.getRuntime().exec( "javac "+javaFile );
// Attend la fin de la compilation
essayer {
p.waitFor();
} catch (InterruptedException c'est à dire) { System.out.println (c'est à dire) ;
// Vérifiez le code retour pour voir s'il y a des erreurs de compilation.
int ret = p.exitValue();
//Renvoie si la compilation a réussi.
retourner ret==0 ;
}
// Le code principal du chargeur de classes - le chargement des classes compile automatiquement les fichiers sources en cas de besoin.
classe publique loadClass (nom de la chaîne, résolution booléenne)
lance ClassNotFoundException {
//Notre objectif est d'obtenir un objet de classe.
Classe classe = null ;
// Tout d'abord, vérifiez si cette classe a été traitée.
clas = findLoadedClass( nom );
//System.out.println( "findLoadedClass: "+clas );
// Récupère le nom du chemin via le nom de la classe, par exemple : java.lang.Object => java/lang/Object
String fileStub = name.replace( ''''.'''', ''''/'''' );
// Construire des objets pointant vers des fichiers sources et des fichiers de classe.
String javaFilename = fileStub+.java";
String classFilename = fileStub+.class";
Fichier javaFile = nouveau fichier (javaFilename);
Fichier classFile = nouveau fichier (classFilename);
//System.out.println( "j "+javaFile.lastModified()+" c "
//+classFile.lastModified() );
// Tout d'abord, déterminez si la compilation est requise. Si le fichier source existe mais que le fichier de classe n'existe pas, ou si les deux existent mais le fichier source
// Plus récent, indiquant qu'il doit être compilé.
if (javaFile.exists() &&(!classFile.exists() ||
javaFile.lastModified() > classFile.lastModified())) {
essayer {
// Compile, si la compilation échoue, nous devons déclarer la raison de l'échec (il ne suffit pas d'utiliser des classes obsolètes).
if (!compile( javaFilename ) || !classFile.exists()) {
lancer une nouvelle ClassNotFoundException( "Échec de la compilation : "+javaFilename );
}
} catch (IOException c'est à dire) {
// Une erreur IO peut survenir lors de la compilation.
lancer une nouvelle ClassNotFoundException (ie.toString ());
}
}
// Assurez-vous qu'il a été compilé correctement ou qu'il ne nécessite pas de compilation, nous commençons à charger les octets bruts.
essayer {
// Lit les octets.
octet brut[] = getBytes( classFilename );
//Convertir en objet de classe
clas = définirClass( nom, brut, 0, brut.longueur );
} catch (IOException c'est à dire) {
// Cela ne signifie pas un échec, peut-être que la classe à laquelle nous avons affaire se trouve dans la bibliothèque de classes locale, telle que java.lang.Object.
}
//System.out.println( "defineClass: "+clas );
//Peut-être dans la bibliothèque de classes, chargée par défaut.
si (clas==null) {
clas = findSystemClass( nom );
}
//System.out.println( "findSystemClass: "+clas );
// Si le paramètre solve est vrai, interprétez la classe selon vos besoins.
if (résoudre && clas != null)
solveClass(clas);
// Si la classe n'a pas été obtenue, quelque chose s'est mal passé.
si (classe == null)
lancer une nouvelle ClassNotFoundException (nom);
// Sinon, renvoie cet objet de classe.
classe de retour ;
}
}
CCRun.java
Voici le fichier CCRun.java
importer java.lang.reflect.* ;
/*
CCLRun charge les classes via CompilingClassLoader pour exécuter le programme.
*/
classe publique CCLRun
{
static public void main( String args[] ) lève une exception {
//Le premier paramètre spécifie la classe de fonctions principale que l'utilisateur souhaite exécuter.
Chaîne progClass = args[0];
//Les paramètres suivants sont les paramètres passés à cette classe de fonctions principale.
Chaîne progArgs[] = new String[args.length-1];
System.arraycopy( args, 1, progArgs, 0, progArgs.length );
// Créer un chargeur de classe de compilation
CompilingClassLoader ccl = new CompilingClassLoader();
//Chargez la classe de fonctions principale via CCL.
Classe clas = ccl.loadClass( progClass );
// Utilisez la réflexion pour appeler sa fonction principale et transmettre les paramètres.
// Génère un objet de classe représentant le type de paramètre de la fonction principale.
Classe mainArgType[] = { (new String[0]).getClass() };
// Recherche la fonction principale standard dans la classe.
Méthode main = clas.getMethod( "main", mainArgType );
// Crée une liste de paramètres - dans ce cas, un tableau de chaînes.
Objet argsArray[] = { progArgs };
// Appelez la fonction principale.
main.invoke( null, argsArray );
}
}
Foo.java
Voici le contenu du fichier Foo.java
classe publique Foo
{
static public void main( String args[] ) lève une exception {
System.out.println( "foo! "+args[0]+" "+args[1] );
nouvelle barre (args[0], args[1] );
}
}
Bar.java
Voici le contenu du fichier Bar.java
importer baz.*;
Bar de classe publique
{
barre publique (Chaîne a, Chaîne b) {
System.out.println( "bar! "+a+" "+b );
nouveau Baz( a, b );
essayer {
Classe booClass = Class.forName( "Boo" );
Objet boo = booClass.newInstance();
} catch(Exception e) {
e.printStackTrace();
}
}
}
baz/Baz.java
Voici le contenu du fichier baz/Baz.java
paquet baz;
classe publique Baz
{
public Baz (Chaîne a, Chaîne b) {
System.out.println( "baz! "+a+" "+b );
}
}
Boo.java
Voici le contenu du fichier Boo.java
classe publique Bouh
{
publicBoo() {
System.out.println( "Bouh!" );
}
}
Partie 7. Résumé Résumé Après avoir lu cet article, avez-vous réalisé que la création d'un chargeur de classes personnalisé vous permet d'approfondir les composants internes de la machine virtuelle Java. Vous pouvez charger un fichier de classe à partir de n'importe quelle ressource, ou le générer dynamiquement, afin de pouvoir faire beaucoup de choses qui vous intéressent en étendant ces fonctions, et vous pouvez également compléter certaines fonctions puissantes.
Autres sujets concernant ClassLoader Comme mentionné au début de cet article, les chargeurs de classes personnalisés jouent un rôle important dans les navigateurs intégrés Java et les navigateurs d'applets.