class loading是一个比较复杂的过程。一般说来,类是在其static member被访问时被加载的。在加载时会做的一件事是:初始化static member和static代码段(static block, i.e. static {......}),当然,static是只会被执行only once的。
以下是一个例子(adapted from Chapter 7, Thinking in Java, Fourth Edition):
//@file Beetle.java
import static java.lang.System.out;
class Insect
{
private int i = 1;
protected int j;
private static int x1 = printInit("static Insect.x1 initialized");
Insect()
{
out.println("Insect constructor");
out.println("i = " + i + ", j = " + j + ", x1 = " + x1);
this.j = 2;
}
static int printInit(String s)
{
out.println(s);
return 3;
}
}
public class Beetle extends Insect
{
private int k = printInit("Beetle.k initialized");
private static int x2 = printInit("static Beetle.x2 initialized");
public Beetle()
{
out.println("Beetle constructor");
out.println("j = " + j + ", k = " + k + ", x2 = " + x2);
}
public static void main(String[] args)
{
Beetle b = new Beetle();
}
}
//output:
/*
static Insect.x1 initialized
static Beetle.x2 initialized
Insect constructor
i = 1, j = 0, x1 = 3
Beetle.k initialized
Beetle constructor
j = 2, k = 3, x2 = 3
*/
->首先,访问Beetle.main(),是个static,好,加载Beetle.class;
-->发现Beetle extends Insect,好,加载Insect.class(如果Insect还有base class,则持续这一过程,直到找到root base class);
---->初始化private static int x1( = 3),打印"static Insect.x1 initialized";
---->Insect.class加载完毕
-->继续加载Beetle.class;
---->初始化private static int x2( = 3),打印"static Beetle.x2 initialized";
---->Beetle.class加载完毕,
->开始执行Beetle.main();
-->要new一个Beetle,须先new一个Insect;
---->在执行Insect constructor前,先要初始化member,由于private static int x1是static且已经初始化了,所以这次只初始化private int i( = 1)和protected int j( = 0 by default);
---->执行Insect constructor,打印"Insect constructor"和"i = 1, j = 0, x1 = 3",然后j = 2;
---->Insect constructor执行完毕,即new Insect过程完毕
-->继续new Beetle;
---->同理,在执行Beetle constructor之前,要先初始化member,这里是初始化private int k( = 3),打印"Beetle.k initialized";
---->执行Beetle constructor,打印"Beetle constructor"和"j = 2, k = 3, x2 = 3";
---->Beetle constructor执行完毕,即new Beetle过程完毕
->Beetle.main()执行完毕。
(2009年03月27日补充:more details see [#0x000B])
(2009年09月04日归纳:[#0x0023])