Maison > Questions et réponses > le corps du texte
怪我咯2017-04-18 10:53:03
Afin de comprendre la différence entre Class.forName
et ClassLoader.loadClass
, nous devons d'abord comprendre les étapes de chargement des classes dans JVM
Le chargement des classes peut être divisé en les étapes suivantes
Chargement : récupérez le flux binaire de la classe via son nom complet, puis chargez-le dans la JVM
Vérification : assurez-vous que les informations contenues dans le flux d'octets du fichier Class répondent aux exigences de la machine virtuelle et ne mettront pas en danger la sécurité de la machine virtuelle
Préparation : Allouer de l'espace mémoire pour les variables de classe et définir la valeur initiale de la variable de classe
Analyse
Initialisation : initialisez les champs et autres ressources selon le code spécifié par l'utilisateur, en exécutant des blocs statiques.
Quand on passe :
Class.forName("com.test.MyObj")
Lorsque est utilisé pour obtenir une classe, cela équivaut en fait à appeler Class.forName(className, true, currentLoader)
. Le deuxième paramètre de cette méthode indique si la classe doit être initialisée à true
, donc lorsque Class.forName obtient. l'objet Class, ce sera La classe est automatiquement initialisée.
Et le ClassLoader de la classe chargée par Class.forName est le même que le ClassLoader de la classe où Class.forName
est appelé.
est différent de Class.forName
. Par défaut, ClassLoader.loadClass
n'initialise pas la classe, c'est-à-dire que l'étape 初始化
de chargement de la classe n'est pas exécutée, donc le bloc de code statique de la classe ne sera pas exécuté.
et utilisez ClassLoader.loadClass
, nous pouvons spécifier différents ClassLoader Par exemple :
ClassLoader.getSystemClassLoader().loadClass("com.test.MyObj");
public class MyObj {
static {
System.out.println("MyObj class init.");
}
}
public class Test implements Cloneable, Serializable {
public static void main(String[] args) throws Exception {
Class.forName("com.test.MyObj");
// ClassLoader.getSystemClassLoader().loadClass("com.test.MyObj");
}
}
Dans le code ci-dessus, l'appel de Class.forName("com.test.MyObj")
déclenchera l'exécution du bloc de code statique de MyObj, mais ClassLoader.getSystemClassLoader().loadClass("com.test.MyObj");
ne le fera pas.
Mon hypothèse personnelle est que cela devrait être lié au chargement paresseux de Spring IoC. Afin d'accélérer l'initialisation, Spring IoC utilise de nombreuses technologies de chargement retardé. L'utilisation de classloader n'a pas besoin d'exécuter le code d'initialisation dans la classe. ce qui peut accélérer le chargement. Le travail d'initialisation de la classe est laissé jusqu'à ce que la classe soit réellement utilisée.