您的位置:首页 > 编程语言 > Java开发

Java类的初始化顺序探究

2017-04-10 15:02 176 查看
有时候对于类的初始化顺序会有点迷糊,最近看了《Java编程思想》,选取了书中(第四版)146页的一段代码进行探究。

package unit9;

class Insect {
private int i = 9;
protected int j;

Insect() {
System.out.println("i= " + i + ", j= " + j);
j = 39;
}

private static int x1 = printInit("static Insect.x1 initialized");

static int printInit(String s) {
System.out.println(s);
return 47;
}
}

public class Beetle extends Insect {
private int k = printInit("Beetle.k initialized");

public Beetle() {
System.out.println("k= " + k);
System.out.println("j= " + j);
}

private static int x2 = printInit("static Beetle.x2 initialized");

public static void main(String[] args) {
System.out.println("Beetle Constructor");
Beetle b = new Beetle();
}

}


其输出结果是:
static Insect.x1 initialized (1)
static Beetle.x2 initialized (2)
Beetle Constructor (3)
i= 9, j= 0 (4)
Beetle.k initialized (5)
k= 47 (6)
j= 39 (7)


分析如下:
首先先知道一个概念,类是在其任何static成员被访问时加载的。在Beetle上运行Java时,所发生的第一件事就是试图访问Beetle.main()(一个static方法),于是加载器开始启动并找出Beetle的编译代码(在名为Beetle.class的文件之中)。在对它进行加载的过程中,编译器注意到它有一个父类(superclass)(这是通过关键字extends得知的),于是编译器要首先加载Beetle类的父类Insect类,不管你是不是打算产生一个Insect的对象,Insect类都要被加载。如果Insect类还有其父类,那么Insect类的父类将先被加载,以此类推。

根据上面的代码开始类的加载,根据在代码中的顺序,所有的static对象和static代码段都会被初始化。首先Insect类被加载:静态变量x1先被初始化,静态方法printInit被初始化,所以输出结果(1),Insect类加载结束。然后加载Beetle类:静态变量x2被初始化,所以输出结果(2)。Beetle.main()方法所用到的两个类都被加载完成之后,开始执行Beetle.main()中的代码,首先输出结果(3)。然后声明了一个类型为Beetle的对象b,调用构造器对其初始化。首先初始化父类的非静态变量(没有默认值的初始化为
0、false或null),所以i=9,j=0。之后调用父类的构造器,输出结果(4)并且j被赋值为39。然后初始化子类的非静态变量:k被赋值为47并输出结果(5),之后再实行子类构造器,输出结果(6)及结果(7)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: