java程序初始化的顺序是什么样的?[中高]

版权声明:No Rain No Rainbow https://blog.csdn.net/xiangyuenacha/article/details/84232724

Java程序初始化一般遵循3个原则:

  1. 静态对象(变量)优先于非静态对象(变量)初始化。其中静态对象(变量)只初始化一次,而非静态对象(变量)可能会初始化很多次
  2. 父类优先于子类进行初始化
  3. 按照成员变量的定义顺序进行初始化。即使变量定义散布于方法之中,他们依然在任何方法(包括构造函数)被调用前先初始化

总结:
父类静态字段初始化
父类静态代码块
子类静态字段初始化
子类静态代码块
父类普通字段初始化
父类构造代码块
父类构造函数
子类普通字段初始化
子类构造代码块
子类构造函数

可以很明显的看出:static字段、代码块的执行顺序优先于非static字段、代码块。这是因为在静态域是属于类的,在类加载后就一直存在;而普通域需要创建对象才能访问。而在创建对象时,需要先加载父类,然后再加载子类,因此父类的静态字段初始化和静态代码块执行先于子类。

参考代码: CodeBlockTest

// 测试Java程序初始化的顺序
public class CodeBlockTest {
	public static void main(String[] args) {
		Child child = new Child();
	}
}

class Father {
	public static String fatherStr1 = "fatherStr1(静态字段初始化值)";

	public String fatherStr2 = "fatherStr2(字段初始化值)";
	static {
		System.out.println("父类静态代码块:" + fatherStr1 +",静态变量已经初始化");
		fatherStr1 = "fatherStr1(静态代码块赋值)";
	}
	{
		System.out.println("父类构造代码块fatherStr1:" + fatherStr1);
		System.out.println("父类构造代码块fatherStr2:" + fatherStr2);
		fatherStr2 = "fatherStr2(构造代码块赋值)";
	}

	public Father() {
		System.out.println("父类构造函数:" + fatherStr2);
		fatherStr2 = "fatherStr2(构造函数赋值)";
	}
}

class Child extends Father {
	public static String childStr1 = "childStr1(静态字段初始化值)";
	public String childStr2 = "childStr2(字段初始化值)";
	static {
		System.out.println("子类静态代码块:" + childStr1 + ",静态变量已经初始化");
		childStr1 = "childStr1(静态代码块赋值)";
	}
	{
		System.out.println("子类构造代码块childStr1:" + childStr1);
		System.out.println("子类构造代码块childStr2:" + childStr2);
		childStr2 = "childStr2(构造代码块赋值)";
	}

	public Child() {
		System.out.println("子类构造函数:" + childStr2);
		childStr2 = "childStr2(构造函数赋值)";
	}
}
/*父类静态代码块:fatherStr1(静态字段初始化值),静态变量已经初始化
子类静态代码块:childStr1(静态字段初始化值),静态变量已经初始化
父类构造代码块fatherStr1:fatherStr1(静态代码块赋值)
父类构造代码块fatherStr2:fatherStr2(字段初始化值)
父类构造函数:fatherStr2(构造代码块赋值)
子类构造代码块childStr1:childStr1(静态代码块赋值)
子类构造代码块childStr2:childStr2(字段初始化值)
子类构造函数:childStr2(构造代码块赋值)*/

猜你喜欢

转载自blog.csdn.net/xiangyuenacha/article/details/84232724