Summary: class loading, initialization implementation order

Class loading focuses on a few steps.


When the virtual machine starts, the user needs to specify a main class to be executed (the class containing the main() method) to

 load : load the main class


Preparation : Allocate memory for class variables and set the initial value of class variables (0 or NULL). If there are static final variables (objects), assign static variables (objects) in the preparation stage.
Class variable: static modified variable: O or NULL
static final variable: because the initial value must be assigned when it is defined, it is directly assigned in the preparation stage.
Instance variables: Allocated in the heap along with the object when the object is instantiated.

 

Initialization : Initialize variables and other resources sequentially.


The new keyword instantiates an object;

Read or set a class variable (static modification), call the static method of the class. If there are static objects, static variables, static code block initialization;

If there is a parent class that has not been initialized, you need to trigger the initialization of the parent class first.

Make a reflective call to the class.

etc.

E.g:

 

package test;

public class Test {
	Father father2 = new Father("Ordinary member Father2 constructor");
	static {
		System.out.println("Static block execution");
	}
	{
		System.out.println("Ordinary code block execution");
	}
	static Father father1 = new Father("Static member Father1 constructor");
	
	Father father3 = new Father("Ordinary member Father3 constructor");

	public Test(){
		System.out.println("Test class default constructor call");
	}
	public static void main(String[] args) {
		System.out.println("The first main class object");
		Test test1 = new Test();
		
		System.out.println("The second main class object");
		Test test2 = new Test();
	}
}

class Father {
	public Father(String s) {
		System.out.println(s);
	}

	{
		System.out.println("******father init");
	}
	static {
		System.out.println("*******father static init");
	}
}

 

 Results of the:

 

static block execution
*******father static init
******father init
Static member Father1 constructor
first main class object
******father init
Ordinary member Father2 constructor
normal code block execution
******father init
Ordinary member Father3 constructor
Test class default constructor call
The second main class object
******father init
Ordinary member Father2 constructor
normal code block execution
******father init
Ordinary member Father3 constructor
Test class default constructor call

 

analyze:

 1. When executing the main() method, load the main class Test and initialize it first.

During initialization, the static objects, static variables, and static code blocks of the main class are initialized (in order). So the static code block of the Test class, the static object father1 is initialized. (output lines 1-4)

Among them, when the static object father1 is initialized, the class Father needs to be loaded and initialized. Similarly, when the Father class is initialized, the static code block is initialized. During the loading process of a class, the constructor of . After all variables are initialized, the constructor will be executed.

Finally call the constructor.

2、Test test1 = new Test();(输出6-11行)

初始化Test类,静态成员和静态代码块只进行了一次初始化。

 

所以只初始化Test类的普通对象和普通代码块。

3、Test test2 = new Test();(输出13-18行)

 

注意:

1、类的静态成员和静态代码块在类加载中是最先进行初始化的,并且只进行一次。

 

2、执行顺序为:

  1. static静态代码块和静态成员
  2. 普通成员
  3. 构造函数执行

 

3、类加载检查:

 

JVM遇到一条new指令时,首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行相应的类的加载过程。

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326647597&siteId=291194637