Si vous souhaitez utiliser un chargeur de classe personnalisé pour charger le fichier de classe, vous devez hériter de la classe java.lang.classloader.
Il existe plusieurs méthodes importantes pour Classloader:
ProtectedClassloader (ClassloadEader): crée un nouveau chargeur de classe à l'aide du chargeur de classe parent spécifié pour les opérations de délégué.
ProtectedFinalClass <?> DefinClass (StringName, Byte [] B, Intoff, Intlen): convertissez un tableau d'octets en une instance de la classe de classe.
ProtectedClass <?> findClass (StringName): Recherchez la classe avec le nom binaire spécifié.
publicClass <?> LoadClass (StringName): Chargez la classe avec le nom binaire spécifié.
ProtectedFinalClass <?> findloadDClass (StringName): Si la machine virtuelle Java a enregistré ce chargeur en tant que chargeur de démarrage d'une classe avec un nom binaire donné, la classe avec ce nom binaire est renvoyée. Sinon, retournez null.
publicFinalClassloaderGetParent (): Renvoie le chargeur de classe parent délégué.
ProtectedFinalVoidResolVeClass (classe <?> C): lien vers la classe spécifiée.
Si vous souhaitez suivre le modèle de délégation parent, réécrivez la méthode FindClass (StringName); Si vous ne souhaitez pas suivre le modèle de délégation parent, réécrivez directement la méthode LoadClass (StringName).
Personnaliser les chargeurs de classe qui suivent le modèle de délégation parentale
Parentsdelegateclassloader.java
Package com.zzj.classloader; import java.io.bytearrayoutputStream; import java.io.file; import java.io.fileInputStream; importer java.io.ioexception; import java.io.inputstream; / ** * Parents Delegate Class chargeur and override findclass (name) méthode * * @author administrateur * / public Class Public Classic ParentsDelegateClassloader étend Classloader {private static final String ext = ".class"; PRIME String Path; Public ParentsDelegateClassloadher () {path = this.getResource (""). GetPath ();} Public ParentsdelegateClassloadher (String Path) {this.path = path;} @ overde Protected class <? ClassNotFoundException {byte [] b = null; try {b = loadClassFile (name);} catch (ioException e) {e.printStackTrace ();} return this.deFineClass (name, b, 0, b.length);} private byte [] loadclassfile (string name) throw getClassFile (name); System.out.println ("Le fichier de classe sera bientôt chargé" + classfile); bytearRayOutStream out = new bytearrayoutputStream (); inputStream input = new FileInputStream (classfile); int count; byte [] temp = new byte [1024]; {out.write (temp, 0, count);} out.close (); input.close (); return out.toByTearray ();} private string getClassfile (String name) {String pathname = name.replace (".", file.separator); if (path.endswith ("/") || path.endswith ("//") {return pathname + Path.endSwith ("//") {return pathname + Path. Ext;} return path + file.separator + pathname + ext;}}Maintenant, il existe un fichier de classe com / zzj / classloadher / user.class sous le répertoire de classe de classe ClassPath et F: // ClassloaderTest // Bin. Le nom du package est com.zzj.classloader. Utilisez le chargeur de classe ParentsDelegateClassloadher pour charger la classe sous F: // ClassloaderTest // Bin.
Package com.zzj.classloader; Application de classe publique {Private Static Final String Path = "F: // classloaderTest // bin"; private static final String classname = "com.zzj.classloader.user"; public static void Main (String [] args) lance une exception {ParentsDelegateClassOader <? classloader.loadClass (className); System.out.println (Clazz); System.out.println (Clazz.getClassloader ());}}Sortir:
classe com.zzj.classloader.user sun.misc.launcher$AppCLASSOLODER@19821F
Le chargeur de la classe utilisateur est le chargeur de classe système AppClassloadher, pas le chargeur de classe que nous définissons nous-mêmes. En fait, ce n'est pas la classe sous f: // CLASSOLOLOTERTEST // BIN, mais la classe sous ClassPath. Il s'agit du modèle de délégation parent: lorsque le chargeur ParentsDelegateClassLoader reçoit la demande de chargement, il déléguera d'abord au chargeur de classe parent. Si le chargeur de classe parent se charge avec succès, un objet de classe sera renvoyé. Si la charge échoue, le chargeur de classe qui a reçu la demande de charge sera chargé.
Supprimez la classe utilisateur sous ClassPath pour tester Run:
Le fichier de classe sera bientôt chargé f: /classloadertest/bin/com/zzj/classloader/user.class class com.zzj.classloader.user com.zzj.classloader.parentsdelegateclassloader@61de33
À l'heure actuelle, la classe utilisateur se charge en tant que parentsdegateclassloadher.
Cela peut être vérifié à partir du code source de Classloader:
public class <?> LoadClass (String Name) lève ClassNotFoundException {return LoadClass (name, false); }La méthode surchargée a été appelée:
Classe synchronisée protégée <?> LoadClass (nom de chaîne, boolean résolve) lève classNotFoundException {// Déterminez d'abord si la classe a été chargée par la classe de classe actuelle Classe C = findloadEDClass (name); if (c == null) {try {if (parent! = null) {// Si le chargeur de classe parent existe, alors déléguez à la classe parent pour charger c = parent.loadClass (name, false); } else {// Si la classe parent charge vide, son chargeur de classe parent est le chargeur de classe de démarrage c = findbootstrapClass0 (name); }} catch (classNotFoundException e) {// Si le chargeur de classe parent ne se charge pas, il se chargera et appellera la méthode FindClass! c = findClass (name); }} if (résolve) {résolveclass (c); } return c; }On peut voir que si vous souhaitez détruire le modèle de délégation parent, vous pouvez réécrire directement la méthode LoadClass (StringName).
Personnaliser les chargeurs de classe qui ne suivent pas le modèle de délégation parentale
Notparentsdelegateclassloader.java
package com.zzj.classloader; import java.io.bytearrayoutputStream; importer java.io.file; import java.io.fileInputStream; import java.io.filenotfoundException; import java.io.ioexception; import java.io.inputStream; / ** * non-battant du délegation chargeur, overclos @Author Administrator * * / public class notparentsDelegateClassloader étend classloader {private static final string ext = ".class"; Private String Path; public notparentsDelegateClassLoader () {path = this.getResource (""). getPath ();} public notparentsDelegateClassoLoder (String path) {that. Classe <?> LoadClass (nom de chaîne) lance classNotFoundException {byte [] b = null; try {b = loadclassfile (name);} catch (filenotFoundException e) {System.err.println ("Loder" + this.getClass (). GetName () + "Aucun fichier de classe n'a trouvé" + nom + ", délegated to the parent clador!"); Le chargeur de classe parent return getClass (). getClassloadher (). LoadClass (name);} catch (ioException e) {System.err.println ("Loader" + this.getClass (). getName () + "Chargeing Class Fichier" + Name + "a échoué, délégué à la classe Parent Class Loder!"); getClass (). getClassLoader (). LoadClass (nom);} // Vérifiez si la classe a été chargée par la classe de classe actuelle (vérifiez uniquement le chargeur de classe actuel, si (non la classe parent) {System.out.out.println ("classe" + nom + "chargé!"); {System.out.println ("class" + name + "pas encore chargé!");} Return this.defineclass (nom, b, 0, b.length);} byte privé [] LoadClassFile (nom de chaîne) lance ioException, filenotfoundException {String classfile = getClassFile (name); System.out.trintLn ("le fichier de classe sera charge". ClassFile); byteArAyOutputStream out = new ByteArrayOutputStream (); InputStream Input = new FileInputStream (classfile); int count; byte [] temp = new Byte [1024]; while ((count out.toByTearray ();} private String getClassFile (String name) {String pathname = name.replace (".", file.separator); if (path.endswith ("/") || path.endswith ("//")) {return path + pathname + ext;} return path + file.separator + pathname + ext;}}}Maintenant, il existe un fichier de classe com / zzj / classloader / user.class sous le ClassPath ClassPath, avec le nom du package com.zzj.classloader, et la classe utilisateur est Loder NotparentsDelegateClassLoader.
package com.zzj.classloader; public class app2 {private static final string classname = "com.zzj.classloadher.user"; public static void main (string [] args) lance l'exception {notparentsdelegateclassloader classloader = newparentsDelegateClassLoader (); class <?> Clazz = classloader.loadClass (className); System.out.println (Clazz); System.out.println (Clazz.getClassloader ());}}Sortir:
Le fichier de classe /e:/myeclipse/zzjtest/webroot/web-inf/classes/com/zzj/classloader/user.class class com.zzj.classloader.user n'a pas encore été chargé! Le fichier de classe sera chargé bientôt / e: /myeclipse/zzjtest/webroot/web-inf/classes/java/lang/object.class class com.zzj.classloadher.user com.zzj.classloader. Le fichier de classe java.lang.object n'est pas trouvé et sera délégué au chargeur de classe parent!
À l'heure actuelle, le chargeur de la classe utilisateur est NotparentsDelegateClassloadher, qui n'est pas délégué à la classe parent d'abord. Il ne sera délégué au chargeur de classe parent que si la charge échoue. Cela se trouve être l'opposé du modèle de délégation parent.
Bien sûr, même si la charge échoue, elle peut être spécifiée sans déléguer au chargeur de classe parent, afin que le mécanisme de chargement de classe de modèles de maillage plus complexes puisse être construit.
Résumer
Ce qui précède concerne l'exemple de code du chargeur de classe personnalisé Java, j'espère que cela sera utile à tout le monde. Les amis intéressés peuvent continuer à se référer à d'autres sujets connexes sur ce site. S'il y a des lacunes, veuillez laisser un message pour le signaler. Merci vos amis pour votre soutien pour ce site!