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

Detaillierte Erklärung des JAVA-Klassenlademechanismus (empfohlen)

Der JAVA-Quellcode-Kompilierung besteht aus drei Prozessen:

1、Quellcode-Kompilierungsmechanismus.

2、Class-Loading-Mechanismus

3、Class-Ausführungsmechanismus

Wir beschreiben hier hauptsächlich die beiden Mechanismen: die Kompilierung und das Class-Loading.

Eins, Quellcode-Kompilierung

Der Code-Kompilierung wird durch den JAVA-Quellcode-Compiler durchgeführt. Es handelt sich hauptsächlich um die Kompilierung der Quelldateien in Bytecode-Dateien (class-Dateien). Das Format der Bytecode-Dateien besteht hauptsächlich aus zwei Teilen: dem Constant Pool und dem Methoden-Bytecode.

Zwei, Class-Loading

Das Lebenszyklus einer Klasse beginnt damit, in den Arbeitsspeicher der Virtual Machine geladen zu werden, und endet mit dem Entladen aus dem Speicher. Dieser Prozess hat sieben Phasen, von denen alle bis zur Initialisierung dem Class-Loading zuzuordnen sind.

Laden----Überprüfung----Vorbereitung----Analyse-----Initialisierung----Verwendung-----Entladen

Das System lädt möglicherweise eine Klasse beim ersten Aufruf, oder es wird ein Vorauslademechanismus verwendet, um eine Klasse zu laden. Wenn ein Java-Programm ausgeführt wird, wird ein Java-Virtual-Machine-Prozess gestartet. Zwei ausgeführte Java-Programme sind in zwei verschiedenen JVM-Prozessen, und diese JVMs teilen keine Daten.

1、Ladephase

Dieser Ladevorgang ist ein Stadium des Class-Loading-Mechanismus, und diese beiden Konzepte sollten nicht verwechselt werden. In diesem Stadium müssen bestimmte Aufgaben erfüllt werden:

1)Durch die vollständige Namensnotation der Klasse wird der Binärbestand dieser Klasse definiert.

2)Die statische Speicherstruktur, die durch diesen Byte-Stream repräsentiert wird, wird in eine laufzeitbezogene Datenstruktur im Methodenbereich umgewandelt.

3)Im Java-Heap wird ein Class-Objekt erstellt, das als Zugangspunkt zu diesen Daten im Methodenbereich dient.

Daß der erste Punkt nicht angibt, woher und wie die Binärbäste der Klasse gewonnen werden sollen, gibt den Entwicklern viel Freiraum. Dies werde ich im folgenden Kapitel über den Class-Loader erläutern.

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);
 }
}

执行结果:

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];
 }
}

执行结果:

3、引用常量时,不会触发该类的初始化

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);
 }
}

执行结果:

MIGU

使用final修饰某个类变量时,它的值在编译时就已经确定并放入常量池中,因此在访问该类变量时,等于直接从常量池中获取,并没有初始化该类。

初始化步骤

1、如果该类尚未加载和连接,则程序先加载该类并连接。

2、如果该类的直接父类尚未加载,则先初始化其直接父类。

3、如果类中有初始化语句,系统将依次执行这些初始化语句。

在第二个步骤中,如果直接父类又有直接父类,系统会再次重复这三个步骤来初始化这个父类,依次类推。JVM最先初始化的总是java.lang.Object类。当程序主动使用任何一个类时,系统会确保该类以及所有的父类都会被初始化。

以上是小编向大家介绍的JAVA类加载机制(推荐),希望对大家有所帮助!

声明:本文内容来自网络,版权归原作者所有。内容由互联网用户自发贡献并自行上传,本网站不拥有所有权,未进行人工编辑处理,也不承担相关法律责任。如果您发现涉嫌版权的内容,请发送邮件至:notice#w。3codebox.com(在发送邮件时,请将#更换为@)进行举报,并提供相关证据。一旦查实,本站将立即删除涉嫌侵权的内容。

Mag sein