English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Explication détaillée du mécanisme de chargement des classes JAVA (recommandé)

La compilation du code source Java est composée de trois processus :

1、Mécanisme de compilation du code source.

2、Mécanisme de chargement de la classe

3、Mécanisme d'exécution de la classe

Nous allons principalement introduire les deux mécanismes de compilation et de chargement des classes.

Premièrement, compilation du code source

La compilation du code est réalisée par le compilateur de source Java. Il s'agit principalement de compiler le code source en fichiers de bytecode (fichiers class). Le format des fichiers bytecode est principalement divisé en deux parties : le pool de constantes et le bytecode des méthodes.

Deuxièmement, chargement de la classe

La vie d'une classe commence lorsqu'elle est chargée dans la mémoire du virtualiseur et se termine par son déschargement. Le processus comprend sept étapes, toutes les étapes avant l'initialisation appartiennent à la phase de chargement de la classe.

Chargement----Vérification----Préparation----Analyse-----Initialisation----Utilisation-----Déschargement

Le système peut charger une classe pour la première fois lors de son utilisation, ou utiliser un mécanisme de pré-chargement pour charger une classe. Lors de l'exécution d'un programme Java, un processus de machine virtuelle Java est démarré. Deux exécutions de programmes Java différents se déroulent dans deux processus JVM différents, et les deux JVM ne partagent pas de données.

1、Étape de chargement

Cette étape de chargement est une phase du mécanisme de chargement des classes, ne pas confondre ces deux concepts, les tâches à accomplir à cette phase incluent :

1Obtient le flux binaire en octets définissant cette classe à partir du nom complet de la classe.

2Convertit la structure de stockage statique représentée par ce flux binaire en structure de données runtime de la zone de méthode.

3Crée un objet Class représentant cette classe dans la pile de Java, servant de point d'entrée pour accéder aux données de la zone de méthode.

En raison du fait que le premier point ne précise pas d'où et comment obtenir le flux binaire en octets de la classe, cette zone laisse beaucoup de place aux développeurs pour s'exprimer. Cela sera expliqué dans le chargeur de classes plus tard.

2、准备阶段

这个阶段正式为类变量(被static修饰的变量)分配内存并设置类变量初始值,这个内存分配是发生在方法区中。

1、注意这里并没有对实例变量进行内存分配,实例变量将会在对象实例化时随着对象一起分配在JAVA堆中。

2、这里设置的初始值,通常是指数据类型的零值。

private static int a = 3;
 这个类变量a在准备阶段后的值是0,将3赋值给变量a是发生在初始化阶段。

3、初始化阶段

初始化是类加载机制的最后一步,这个时候才正真开始执行类中定义的JAVA程序代码。在前面准备阶段,类变量已经赋过一次系统要求的初始值,在初始化阶段最重要的事情就是对类变量进行初始化,关注的重点是父子类之间各类资源初始化的顺序。

java类中对类变量指定初始值有两种方式:1、声明类变量时指定初始值;2、使用静态初始化块为类变量指定初始值。

初始化的时机

1)创建类实例的时候,分别有:1、使用new关键字创建实例;2、通过反射创建实例;3、通过反序列化方式创建实例。

new Test();
Class.forName("com.mengdd.Test");

2)调用某个类的类方法(静态方法)

Test.doSomething();

3)访问某个类或接口的类变量,或为该类变量赋值。 

int b=Test.a;
Test.a=b;

4)初始化某个类的子类。当初始化子类的时候,该子类的所有父类都会被初始化。

5)直接使用java.exe命令来运行某个主类。

除了上面几种方式会自动初始化一个类,其他访问类的方式都称不会触发类的初始化,称为被动引用。

1、子类引用父类的静态变量,不会导致子类初始化。

public class SupClass
{
 public static int a = 123;
 static
 {
  System.out.println("supclass init");
 }
}
public class SubClass extends SupClass
{
 static
 {
  System.out.println("subclass init");
 }
}
public class Test
{
 public static void main(String[] args)
 {
  System.out.println(SubClass.a);
 }
}

Résultat de l'exécution :

supclass init
123

2、通过数组定义引用类,不会触发此类的初始化

public class SupClass
{
 public static int a = 123;
 static
 {
  System.out.println("supclass init");
 }
}
public class Test
{
 public static void main(String[] args)
 {
  SupClass[] spc = new SupClass[10];
 }
}

Résultat de l'exécution :

3、 L'utilisation de constantes ne déclenche pas l'initialisation de la classe

public class ConstClass
{
 public static final String A= "MIGU";
 static
 {
  System.out.println("ConstCLass init");
 }
}
public class TestMain
{
 public static void main(String[] args)
 {
  System.out.println(ConstClass.A);
 }
}

Résultat de l'exécution :

MIGU

Lorsque l'on utilise final pour modifier une variable de classe, sa valeur est déterminée lors de la compilation et placée dans le pool de constantes, donc lors de l'accès à cette variable de classe, c'est comme s'il était directement récupéré à partir du pool de constantes, sans initialiser cette classe.

Étapes d'initialisation

1、 Si la classe n'a pas encore été chargée et liée, le programme charge d'abord la classe et la lie.

2、 Si le parent direct de la classe n'a pas été chargé, le parent direct est d'abord initialisé.

3、 Si la classe contient des instructions d'initialisation, le système exécute ces instructions d'initialisation une à une.

Dans la deuxième étape, si le parent direct a à son tour un parent direct, le système répétera à nouveau ces trois étapes pour initialiser ce parent direct, en suivant l'ordre, JVM initialisera toujours d'abord la classe java.lang.Object. Lorsque le programme utilise toute classe, le système garantit que cette classe et toutes ses classes parentes seront initialisées.

Ce que nous avons mentionné ci-dessus est le mécanisme de chargement des classes JAVA présenté par l'éditeur (recommandé), j'espère que cela pourra aider à tous les utilisateurs !

Déclaration : Le contenu de cet article est来源于网络, appartient à l'auteur original, le contenu est apporté par les utilisateurs d'Internet de manière spontanée et téléchargé, ce site ne détient pas de droits de propriété, n'a pas été traité par l'éditeur humain et ne porte pas de responsabilité juridique. Si vous trouvez du contenu suspect de violation de droits d'auteur, vous êtes invité à envoyer un e-mail à : notice#w3Déclaration : Le contenu de cet article est来源于网络, appartient à l'auteur original, le contenu est apporté par les utilisateurs d'Internet de manière spontanée et téléchargé, ce site ne détient pas de droits de propriété, n'a pas été traité par l'éditeur humain et ne porte pas de responsabilité juridique. Si vous trouvez du contenu suspect de violation de droits d'auteur, vous êtes invité à envoyer un e-mail à : notice#w

Vous pourriez aussi aimer