Java类的初始化顺序探究

有时候对于类的初始化顺序会有点迷糊,最近看了《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)。












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值