初始化流程:
- 堆中开辟空间,加载class文件;
- 类变量 & static块 的初始化;
- 实例变量 & 非static块 的初始化;
- 构造器。
- 注意:
类变量会在类加载的连接_准备阶段进行默认初始化,类加载的初始化阶段进行显示初始化;
实例变量在初始化时,如果没有赋值,系统会赋默认初始化值。
- 示例一:
这段代码的执行流程:class X {
Y b = new Y();
X() {
System.out.print("X");
}
}
class Y {
Y() {
System.out.print("Y");
}
}
class Z extends X {
Y y = new Y();
Z() {
System.out.print("Z");
}
public static void main(String[] args) {
new Z(); //结果是 YXYZ
}
}
- 以main方法为程序执行入口;
- 创建Z对象;
- 由于Z 对象继承 X 对象,所以得先初始化 X 对象;
- X 对象成员变量初始化时又 创建了 Y对象,所以得先创建Y对象;
- Y 对象的构造方法中直接打印 “Y”,自此Y 对象初始化完毕;
- 执行 X 对象的构造方法, 打印 “X” ,自此X 对象初始化完毕;
- Z 的成员变量中 创建 Y 对象,初始化 Y 对象,打印 “Y”,Y对象初始化完毕;
- 执行 Z 的 构造方法,打印 “Z” ,自从Z 对象初始化完毕。程序结束!
- 示例二:
对象的初始化顺序:public class HelloA {
public HelloA() {
System.out.println("HelloA");
}
//构造语句块
{
System.out.println("I'm A class");
}
//静态语句块
static {
System.out.println("static A");
}
}
class HelloB extends HelloA {
public HelloB() {
System.out.println("HelloB");
}
{
System.out.println("I'm B class");
}
static {
System.out.println("static B");
}
public static void main(String[] args) {
new HelloB();
}
}
===============控制台===============
staticA
staticB
I'm A class
HelloA
I'm Bclass
HelloB
- 类加载之后,按从上到下(从父类到子类)执行被static修饰的语句;
- 当static语句执行完之后,再执行main方法;
- 如果有语句new了自身的对象,将从上到下执行构造代码块、构造器(两者可以说绑定在一起)。