Chargeur de classe Java
Java ClassLoader est une classe abstraite. Il appartient à un java.lang emballer. Il charge des classes à partir de différentes ressources. Java ClassLoader est utilisé pour charger les classes au moment de l'exécution. En d'autres termes, JVM effectue le processus de liaison au moment de l'exécution. Les classes sont chargées dans la JVM selon les besoins. Si une classe chargée dépend d'une autre classe, cette classe est également chargée. Lorsque nous demandons de charger une classe, il délègue la classe à son parent. De cette manière, l’unicité est conservée dans l’environnement d’exécution. Il est indispensable d'exécuter un programme Java.
supw
Java ClassLoader repose sur trois principes : Délégation , Visibilité , et Unicité .
Types de chargeur de classe
En Java, chaque ClassLoader possède un emplacement prédéfini à partir duquel il charge les fichiers de classe. Il existe les types suivants de ClassLoader en Java :
Chargeur de classe Bootstrap : Il charge les fichiers de classe JDK standard à partir de rt.jar et d'autres classes principales. C'est un parent de tous les chargeurs de classes. Il n'a aucun parent. Lorsque nous appelons String.class.getClassLoader(), il renvoie null et tout code basé sur celui-ci renvoie NullPointerException. Il est également appelé Primordial ClassLoader. Il charge les fichiers de classe depuis jre/lib/rt.jar. Par exemple, classe de package java.lang.
Chargeur de classe d'extensions : Il délègue la demande de chargement de classe à son parent. Si le chargement d'une classe échoue, il charge les classes du répertoire jre/lib/ext ou de tout autre répertoire sous le nom java.ext.dirs. Il est implémenté par sun.misc.Launcher$ExtClassLoader dans JVM.
Chargeur de classe système : Il charge les classes spécifiques à l'application à partir de la variable d'environnement CLASSPATH. Il peut être défini lors de l'appel du programme à l'aide des options de ligne de commande -cp ou classpath. C'est un enfant d'Extension ClassLoader. Il est implémenté par la classe sun.misc.Launcher$AppClassLoader. Tous les ClassLoader Java implémentent java.lang.ClassLoader.
Comment fonctionne ClassLoader en Java
Lorsque la JVM demande une classe, elle appelle une méthode loadClass() de la classe java.lang.ClassLoader en transmettant le nom entièrement classifié de la classe. La méthode loadClass() appelle la méthode findLoadedClass() pour vérifier que la classe a déjà été chargée ou non. Il est nécessaire d’éviter de charger la classe plusieurs fois.
Si la classe est déjà chargée, il délègue la demande au ClassLoader parent pour charger la classe. Si le ClassLoader ne trouve pas la classe, il appelle la méthode findClass() pour rechercher les classes dans le système de fichiers. Le diagramme suivant montre comment ClassLoader charge la classe en Java à l'aide de la délégation.
Supposons que nous ayons une classe Demo.class spécifique à l’application. La demande de chargement de ces fichiers de classe est transférée vers Application ClassLoader. Il délègue à son Extension ClassLoader parent. De plus, il délègue à Bootstrap ClassLoader. Bootstrap recherche cette classe dans rt.jar et puisque cette classe n'est pas là. Demande maintenant le transfert vers Extension ClassLoader qui recherche le répertoire jre/lib/ext et essaie d'y localiser cette classe. Si la classe s'y trouve, Extension ClassLoader charge cette classe. Application ClassLoader ne charge jamais cette classe. Lorsque l'extension ClassLoader ne le charge pas, alors Application ClaasLoader le charge depuis CLASSPATH en Java.
Le principe de visibilité stipule que le ClassLoader enfant peut voir la classe chargée par le ClassLoader parent, mais l'inverse n'est pas vrai. Cela signifie que si Application ClassLoader charge Demo.class, dans ce cas, essayer de charger Demo.class explicitement à l'aide d'Extension ClassLoader lève java.lang.ClassNotFoundException.
Selon le principe d'unicité, une classe chargée par le parent ne doit pas être à nouveau chargée par Child ClassLoader. Ainsi, il est possible d'écrire un chargeur de classe qui viole les principes de délégation et d'unicité et charge la classe par lui-même.
En bref, le chargeur de classe suit la règle suivante :
- Il vérifie si la classe est déjà chargée.
- Si la classe n'est pas chargée, demandez au chargeur de classe parent de charger la classe.
- Si le chargeur de classe parent ne peut pas charger la classe, essayez de la charger dans ce chargeur de classe.
Considérez l'exemple suivant :
public class Demo { public static void main(String args[]) { System.out.println('How are you?'); } }
Compilez et exécutez le code ci-dessus à l'aide de la commande suivante :
javac Demo.java java -verbose:class Demo
-verbeux:classe: Il est utilisé pour afficher les informations sur les classes chargées par JVM. Ceci est utile lors de l’utilisation du chargeur de classes pour charger des classes de manière dynamique. La figure suivante montre le résultat.
Nous pouvons observer que les classes d'exécution requises par la classe d'application (Démo) sont chargées en premier.
Quand les classes sont chargées
Il n'y a que deux cas :
- Lorsque le nouveau code d'octet est exécuté.
- Lorsque le code d'octet fait une référence statique à une classe. Par exemple, Système.out .
Chargement de classe statique ou dynamique
Les classes sont chargées statiquement avec l'opérateur « nouveau ». Le chargement de classe dynamique appelle les fonctions d'un chargeur de classe au moment de l'exécution à l'aide de la méthode Class.forName().
Différence entre loadClass() et Class.forName()
La méthode loadClass() charge uniquement la classe mais n'initialise pas l'objet. Tandis que la méthode Class.forName() initialise l'objet après l'avoir chargé. Par exemple, si vous utilisez ClassLoader.loadClass() pour charger le pilote JDBC, le chargeur de classe ne permet pas de charger le pilote JDBC.
La méthode java.lang.Class.forName() renvoie l'objet de classe couplé à la classe ou aux interfaces avec le nom de chaîne donné. Il lève ClassNotFoundException si la classe n'est pas trouvée.
Exemple
Dans cet exemple, la classe java.lang.String est chargée. Il imprime le nom de la classe, le nom du package et les noms de toutes les méthodes disponibles de la classe String. Nous utilisons Class.forName() dans l'exemple suivant.
Classe: Représente un objet Class qui peut être de n'importe quel type (? est un caractère générique). Le type Class contient des méta-informations sur une classe. Par exemple, le type de String.class est Class. Utilisez Class si la classe modélisée est inconnue.
getDeclaredMethod() : Renvoie un tableau contenant des objets Method reflétant toutes les méthodes déclarées de la classe ou de l'interface représentée par cet objet Class, y compris les méthodes publiques, protégées, par défaut (package) et privées, mais à l'exclusion des méthodes héritées.
getName() : Il renvoie le nom de la méthode représentée par cet objet Method, sous forme de chaîne.
import java.lang.reflect.Method; public class ClassForNameExample { public static void main(String[] args) { try { Class cls = Class.forName('java.lang.String'); System.out.println('Class Name: ' + cls.getName()); System.out.println('Package Name: ' + cls.getPackage()); Method[] methods = cls.getDeclaredMethods(); System.out.println('-----Methods of String class -------------'); for (Method method : methods) { System.out.println(method.getName()); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
Sortir
Class Name: java.lang.String Package Name: package java.lang -----Methods of String class ------------- value coder equals length toString hashCode getChars ------ ------ ------ intern isLatin1 checkOffset checkBoundsOffCount checkBoundsBeginEnd access0 access0