Java构造器、静态对象、非静态对象等的初始化顺序

Java创建类对象时对于构造器,静态对象、非静态对象的初始化有一定的顺序,我简单归纳一下:

class classes {
	public classes(String n) {
		System.out.println("classes constructor.	" + n);
	}
}

class classOne {
	
	static classes class2 = new classes("class2");

	classOne() {
		System.out.println("classOne constructor");
	}
	classes class1 = new classes("class1");
}

class classTwo extends classOne {
	classes class3 = new classes("class3");
	static classes class4 = new classes("class4");

	classTwo() {
		System.out.println("classTwo constructor");
	}
}

public class Test4 extends classTwo {
	classes class5 = new classes("class5");
	static classes class6 = new classes("class6");

	Test4() {
		System.out.println("Test4  constructor");
	}

	public static void main(String[] args) {
		Test4 test4 = new Test4();
	}
}

在这个例子中,类classes是为了下面的类创建对象时能有一定的响应,因为在类中创建基本类型时无法在屏幕看到它被创建的消息,因此我使用了classes作为一个标记,当我创建了一个classes对象且在代码中调用时,会得到相应的响应。

classOne是一个基类,它里面包含了一个静态的classes对象,一个非静态的classes对象,一个构造器。calssTwo继承了classOne,同样地,它也有基类的相同类型的数据定义,为了降低两个类之间初始化顺序的偶然性,我加入了主类Test4继承了classTwo,以模拟多层次的继承关系。

现在,在Test4中的main方法中创建一个Test4对象,在屏幕上的输出如下:

classes constructor. class2
classes constructor. class4
classes constructor. class6
classes constructor. class1
classOne constructor
classes constructor. class3
classTwo constructor
classes constructor. class5

Test4  constructor

我简单解读Java对于这段代码初始化的顺序,首先,创建Test4对象指令发出后,Java查找到Test4还有基类ClassTwo,而classTwo还有基类calssOne,假如classOne还有基类(实际上classOne继承了Java中的Object类,这里不做讨论),它会一直查找,知道找到根本的那个类。找完(也可以称作类的加载)之后,开始执行初始化,首先初始化基类的static成员,即是创建class2这个对象的这段代码,接着是初始化基类的导出类中的static成员,这个初始化一直到最后层次的导出类,我们先称它为过程1。现在static成员被初始化完毕,接着再回到基类,也就是本例中的classOne这个类,初始化它的非static成员,然后调用它的构造器,请注意,这个过程一定是非static成员先于构造器,不管它们在代码中的顺序如何。调用完classOne构造器后,来到calssTwo,初始化它的非static成员,调用它的构造器,接着来到下一个导出类Test4,初始化它的非static成员,调用它的构造器,这样一层一层地执行这种指令,如果从classOne到Test4中间还有多个中间类,那么都会执行这种指令。

至此,一个Test4对象的构建就完成了,归纳起来大概就是:

基类static成员 > 导出类1static成员 > 导出类1的导出类static成员 > ..... > 基类非static成员 > 
基类构造器 > 导出类1非static成员 > 导出类1构造器 > 导出类1的导出类非static成员 > 导出类1的导出类构造器

> ....非static成员 > ....构造器 > 最底层导出类非static成员 > 最底层导出类构造器

此外,记得我刚才标注的过程1,即初始化static成员的这个过程。当我们第一次创建对象时,这个static成员的初始化过程才会发生,此后如果再次创建对象,过程1不再发生,比如我在Test4的main方法种创建完test4这个对象之后,在它后面再加一行代码:

Test4 test42 = new Test4();

那么针对这行的创建结果,响应就是:

classes constructor. class1
classOne constructor
classes constructor. class3
classTwo constructor
classes constructor. class5

Test4  constructor

也就是不再初始化static成员。

原因大概就是:static成员不属于某个具体的类对象,它属于整个类,因此,static成员的初始化只在类第一次加载时发生,对于本例中创建的test4对象,就是发生了类的第一次加载,因此它执行了初始化static,对于之后的test42对象,类不是第一次加载,因此不执行初始化static成员的指令。

以上代码在命令行以及JavaIDE eclipse中均测试一致。

阅读更多
上一篇3dsmax完全安装到非系统盘的解决办法
下一篇Java关于equals()方法和“==”逻辑运算符的区别简介
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭