Search for
Login | Username Password Forgot? | Email: | Create Account
Non English | Popularity: 0 | Entries: 63 | Updated: 3h 57m ago | | Add to My Feeds

想知道流程是怎样的,最简单的方法就是在每一个必要的地方输出一下,类似下断点去debug一样。考虑如下例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//author: Neeke Blog:www.ineeke.com
public class Insect{
 
	private int i = 20;
	protected int j;
 
	Insect(){
 
		System.out.println("i = " + i + ", j = " + j);
		j = 22;
	}
 
	private static int x1 = printInit("静态的Insecct.x1初始化");
 
	static int printInit(String s){
 
		System.out.println(s);
		return 40;
	}
}
 
public class Beetle extends Insect{
 
	private int k = printInit("Beetle.k初始化");
 
	public Beetle(){
		System.out.println("k = " + k);
		System.out.println("j = " + j);
	}
 
	private static int x2 = printInit("静态的Beetle.x2初始化");
 
	public static void main(String[] args){
 
		System.out.println("Beetle构造");
		Beetle b = new Beetle();
	}
}

程序输出结果:

静态的Insect.x1初始化
静态的Beetle.x2初始化
Beetle构造
i = 20, j = 0
Beetle.k初始化
k = 40
j = 22

执行这段Java程序时第一件事是要访问Beetle.main()(一个静态方法),所以加载器便去寻找已编译的Beetle.class文件。在这个加载过程中,加载器通过extends关键字得知它还有一个父类Insect,于是又接着去加载这个父类。值得注意的是,无论你是否实例化了这个父类,这件事都会在加载器中发生。
如果Insect还存在一个父类,那么这第二个父类也将被载入,以此类推。
接下来,静态属性开始在根类(此例中是Insect)中初始化,接着是它的子类,以此类推。这一点非常重要,因为子类的静态初始化很可能依赖于父类成员属性被初始化之后。
此时,所有必要的类都已经被载入,可以创建对象了。首先,该对象中所有的原始数据类型都被置为其初始值,并且对象的引用被置为null。接着,父类的构造方法被调用。在上面的例子中,这个调用是自动的,当然,你也可以在Beetle()构造方法的第一行操作代码中通过super关键字显示的调用。父类的构造与子类有相同的过程及顺序。在父类构造完成后,实例变量被初始化。最终,子类构造方法中的其余部分开始被执行。

或许你会对下面这些文章感兴趣:



More from Neeke's Blog

九月的第一篇 10 Sep 1
我能歘 10 Jul 29
关于职业规划 10 Jul 29
蛋疼的QQ群 10 Jul 29

^ Back To Top