Pourquoi utiliser un chargeur de classe?
En langue java, le chargement des classes est terminé pendant le fonctionnement du programme. Bien que cette stratégie augmente légèrement les frais généraux de performance lors du chargement des cours, il offrira aux applications Java un degré élevé de flexibilité. Par exemple:
1. Écrivez une application axée sur l'interface et peut attendre qu'elle s'exécute avant de spécifier sa sous-classe d'implémentation;
2. Les utilisateurs peuvent personnaliser un chargeur de classe, permettant au programme de charger un flux binaire à partir du réseau ou d'autres endroits dans le cadre du code du programme à l'exécution; (C'est la base du plug-in Android, de l'installation dynamique et de la mise à jour de l'APK)
Pourquoi étudier l'ensemble du processus de chargement en classe?
Mécanisme de chargement de classe
Le JVM charge le fichier de classe en mémoire, vérifie, analyse et initialise les données, et forme enfin l'intégralité du processus de type Java que le JVM peut utiliser directement.
charger
Chargez le contenu bytecode du fichier de classe en mémoire et convertissez les données statiques en une structure de données d'exécution dans la zone de méthode et générez un objet java.lang.Class représentant cette classe dans le tas, comme portail d'accès pour les données de classe de zone de méthode. Ce processus nécessite la participation du chargeur de classe.
Lien
Le processus de combinaison du code binaire de la classe Java dans l'état de course de la JVM
initialisation
<clinit>() . La méthode Class Constructor <clinit>() est générée par le compilateur collectant automatiquement les actions d'attribution de toutes les variables de classe dans la classe et la fusion des instructions dans le bloc de déclaration statique (bloc statique).<clinit>() d'une classe est correctement verrouillée et synchronisée dans un environnement multi-thread.Exemple 1:
classe publique Demo01 {public static void main (String [] args) {a a = new a (); System.out.println (A.Width); }} classe A {public static int largeth = 100; // variable statique, champ statique de champ statique {system.out.println ("classe d'initialisation statique A"); largeur = 300; } public a () {System.out.println ("Créer un objet de classe A"); }}analyser:
illustrer:
Il y a des piles, des tas (lieux d'objets créés) et des zones de méthode en mémoire (en fait un tas spécial)
1. Lorsque le JVM charge Demo01, formez d'abord les données statiques (variables de classe, méthodes de classe, code ...) dans la zone de la méthode. En même temps, un objet java.lang.Class (objet réfléchissant) sera formé dans le tas, représentant la classe Demo01. Grâce à l'objet, la structure binaire de la classe est accessible. Puis chargez les informations de classe A variable, et formez également un objet A dans le tas, représentant la classe A.
2. Lorsque la méthode principale est exécutée, le cadre de pile de méthode principale sera formé dans la pile et une méthode correspond à une trame de pile. Si la méthode principale appelle d'autres méthodes, elle le appuiera un par un dans la pile. Il existe une variable locale A Type A dans la méthode principale. Au début, la valeur de A est nul. Le constructeur de la classe A est appelé à travers nouveau. La méthode A () est générée dans la pile et l'objet A est généré dans le tas. Ensuite, l'adresse d'un objet est versée à A dans la pile. À l'heure actuelle, A a l'adresse d'un objet.
3. Lorsque A.Width est appelé, les données de la zone de méthode sont appelées.
Lorsqu'une classe est chargée par référence, la classe ne sera chargée qu'une seule fois
Référence active de la classe (l'initialisation de la classe se produira certainement)
java.lang.reflect pour passer des appels de réflexion à la classe Une référence passive à la classe (l'initialisation de la classe ne se produira pas)
Exemple 2:
classe publique Demo01 {static {System.out.println ("statique initialisation Demo01"); } public static void main (String [] args) lève une exception {System.out.println ("la méthode principale de Demo01!"); System.out.println (System.getProperty ("java.class.path")); // référence active // new a (); // system.out.println (a.width); // class.forname ("com.sinosoft.test.a"); // référence passive // system.out.println (a.max); // a [] as = new a [10]; System.out.println (B.Width); // La classe B ne sera pas chargée}} La classe B étend A {static {System.out.println ("Initialisation statique B"); }} classe A étend a_father {public static int width = 100; // variable statique, champ de domaine statique public statique final statique int max = 100; statique {System.out.println ("Static Initialisation Classe A"); largeur = 300; } public a () {System.out.println ("Créer un objet de classe A"); }} classe a_father étend l'objet {statique {System.out.println ("Initialisation statique a_father"); }}Résumer
Ce qui précède est l'intégralité du contenu de cet article. J'espère que le contenu de cet article a une certaine valeur de référence pour l'étude ou le travail de chacun. Si vous avez des questions, vous pouvez laisser un message pour communiquer. Merci pour votre soutien à wulin.com.