Java中的类装载和初始化模块

    在Java中,初始化模块是指用一对"{}"括起来的代码,可以与构造方法一起来对对象进行初始化。初始化模块又分为实例初始化模块静态初始化模块(只能由类的静态成员引用,在类装载时进行调用)

    Java中,代码的执行顺序是:


    1.装入类

    1.1递归装入父类,直到继承链上的父类全部装入为止。

    1.2类装入内存之后,静态数据域静态初始块按照在类中出现的顺序进行执行。


    2.调用类的构造方法

    2.1递归调用父类的构造方法,直到父类为java.lang.Object为止。

    2.2初始化实例数据域,并按照它们出现的顺序执行初始化模块。

    2.3执行构造方法的方法体。

package twlkyao;

public class InitializationDemo { 
	
	int a = 1;
	
	public static void main(String[] args) {
		new InitializationDemo(); // 1,a,2,3,4,c,5,6,b,7,8
		new InitializationDemo(); // a,2,c,5,6,b,7,8
	}
	
	// Initialization‘s initializer.
	public InitializationDemo() {
		new M();
	}
	
	// Initialization‘s instance block.
	{
		System.out.println("(2) InitializationDemo‘s instance block");
	}
	
	// Initialization‘s static block.
	static {
		System.out.println("(1) InitializationDemo‘s static block");
	}
} 

class M extends N{
	
	int b = 2;
	
	// M‘s initializer.
	M() {
		System.out.println("(8) M‘s constructor body");
	}
	
	// M‘s instance block.
	{
		System.out.println("(7) M‘s instance block");
	}
	
	// M‘s static block.
	static {
		System.out.println("(4) M‘s static block");
	}
}

class N {
	
	int c = 3;
	
	// N‘s initializer.
	N() {
		System.out.println("(6) N‘s constructor body");
	}
	
	// N‘s instance block.
	{
		System.out.println("(5) N‘s instance block");
	}
	
	// N‘s static block.
	static {
		System.out.println("(3) N‘s static block");
	}
}

    在上面的代码中,程序的执行顺序如下:

    1.由于要装载InitializationDemo类,而在Java中,所有类的基类为Object,需要先装载Object类。

    2.之后调用InitializationDemo类中的静态初始化模块,输出语句(1)。

    3.进入到InitializationDemo的main方法,开始执行。

    4.在main方法中,执行InitializationDemo的构造方法,在执行构造方法的方法体之前,需要按照出现的先后顺序先执行InitializationDemo的实例数据域,这里先执行a = 1,然后输出语句(2)。

    5.执行InitializationDemo的构造函数的函数体,调用类M的构造函数。

    6.由于要执行类M的构造函数,而此时类M没有在内存中,需要先进行装载

    7.由于类M继承自类N,需要先装载类N(由于类java.lang.Object已经装载进了内存,所以不再需要装载),执行类N的静态初始化模块,从而输出语句(3)。

    8.装载类M,执行类M的静态初始化模块,输出语句(4)。

    9.在执行类M的构造函数之前, 先要执行父类N的构造函数,在执行父类N的构造函数之前,先要执行类N中的实例化初始模块,这里先执行c = 3,然后输出语句(5)。

    10.执行类N的构造函数的方法体,输出语句(6)。

    11.接下来要执行类M的构造函数,先要初始化实例数据域,这里先执行b = 2,然后输出语句(7)。

    12.执行类M的构造函数的方法体,输出语句(8)。


    第二次,继续执行InitializationDemo的构造函数,由于所有的类已经装载,只执行构造函数并且初始化实例数据域,所以第二次执行:a = 1,输出语句(2);c = 3,输出语句(5)(6);b = 2,输出语句(7)(8)。

    代码执行过程中的内存中的类如下:越下边的类,越先进行装载


    Java中的类装载和初始化模块

    参考资料:

    《Java语言程序设计——基础篇》

Java中的类装载和初始化模块,布布扣,bubuko.com

Java中的类装载和初始化模块

上一篇:C#程序调用C++写的dll传递string出现bad ptr


下一篇:Effective C++:条款29:为“异常安全”而努力是值得的