这里我们从类加载器把.class文件加载完成后说起,总的来说是先加载成员变量,再加载构造函数。
而成员变量后分为静态成员和非静态成员,先加载静态成员变量,再加载非静态成员变量。
再进一步细分,把成员变量分成代码块中的成员变量和代码块外部的成员变量。这两部分的在初始化等级上是平级的,按声明的先后顺序进行初始化。
当涉及到子类继承父类时,情况其实也不复杂。因为当子类继承父类时,子类继承了父类的非private的成员变量和方法,这些父类成员变量和方法其实已经是子类的了。只是在对子类的变量和构造方法进行初始化时,会先初始化父类的那部分,再初始化子类的。
当初始化的成员变量引用了一个对象时,会先把那个对象初始化完成后,在递归回来进行后续的初始化工作。
初始化顺序是:先成员后构造方法,先静态后非静态,代码块和成员同级,先父类后子类。
下面列举两个网上的例子
例1:
import static com.study.Print.print;
class Bowl{
Bowl(int marker){
print("Bowl("+marker+")");
}
void f1(int marker){
print("f1("+marker+")");
}
}
class Table {
static Bowl bowl1 = new Bowl(1);
Table(){
print("Table()");
bowl2.f1(1);
}
void f2(int marker){
print("f2("+marker+")");
}
static Bowl bowl2 = new Bowl(2);
}
class Cupboard{
Bowl bowl3 = new Bowl(3);
static Bowl bowl4 = new Bowl(4);
Cupboard(){
print("Cupboard()");
bowl4.f1(2);
}
void f3(int marker){
print("f3("+marker+")");
}
static Bowl bowl5 = new Bowl(5);
}
public class StaticInitialzation {
public static void main(String[] args) {
print("Create new Cupboard() in main");
new Cupboard();
print("create new cupboard in main");
new Cupboard();
table.f2(1);
cupboard.f3(1);
}
static Table table = new Table();
static Cupboard cupboard = new Cupboard();
}
/**解答
* 首先加载StaticInitialzation类,初始化类中的两个变量。
* 引起加载Table和Cupboard。
* 加载Table,引起加载bowl1和bowl2,然后调用Table的构造函数Table(),然后执行bowl2的f1方法。
* 加载Cupboard。首先加载静态的bowl4和bowl5,然后加载非静态的bowl3,然后构造函数,然后bowl4的方法。
* 然后进入main函数。
* 创建一个新的Cupboard实例。只加载非静态的Bowl3,不在加载静态的Bowl4和5,静态的只加载一次。
* 执行table的f2(1)方法和cupload的f3方法。
*
* StaticInitialzation
* Table Cupboard
* bowl1 bowl2 Table() f1(1) Bowl(4) Bowl(5) Bowl(3) Cupboard() f1(2)
Bowl(1)
Bowl(2)
Table()
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f1(2)
Create new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
create new cupboard in main
Bowl(3)
Cupboard()
f1(2)
f2(1)
f3(1)
*/
转自http://mengzhiang.iteye.com/blog/1155437
例2
public class PrintClass {
public static void main(String[] args){
new B();
}
PrintClass(String var) {
System.out.println(var);
}
}
class A {
static PrintClass pClassA1 = new PrintClass("A. 静态成员的初始化1");
static {
System.out.println("A. 静态初始化块1");
}
static {
System.out.println("A. 静态初始化块2");
}
static PrintClass pClassA2 = new PrintClass("A. 静态成员的初始化2");
{
System.out.println("A. 实例初始化块1");
}
PrintClass pClassA = new PrintClass("A. 实例成员的初始化");
{
System.out.println("A. 实例初始化块2");
}
public int Avar;
public A() {
System.out.println("A. 构造方法");
doSomething();
}
private void doSomething() {
// public void doSomething() {
Avar = 1111;
System.out.println("Avar=" + Avar);
}
}
//class B extends A
class B extends A
{
public static void main(String[] args){
new B();
}
public int Bvar = 2222;
{
System.out.println("B. 实例初始化块1");
}
{
System.out.println("B. 实例初始化块2");
}
PrintClass pClassB = new PrintClass("B. 实例成员的初始化");
static {
System.out.println("B. 静态初始化块1");
}
static PrintClass pClassB1 = new PrintClass("B. 静态成员的初始化1");
static PrintClass pClassB2 = new PrintClass("B. 静态成员的初始化2");
static {
System.out.println("B. 静态初始化块2");
}
public B() {
System.out.println("B. 构造方法");
doSomething();
}
public void doSomething() {
System.out.println("Bvar=" + Bvar);
}
}
可以看到运行结果为:
A. 静态成员的初始化1
A. 静态初始化块1
A. 静态初始化块2
A. 静态成员的初始化2
B. 静态初始化块1
B. 静态成员的初始化1
B. 静态成员的初始化2
B. 静态初始化块2
A. 实例初始化块1
A. 实例成员的初始化
A. 实例初始化块2
A. 构造方法
Avar=1111
B. 实例初始化块1
B. 实例初始化块2
B. 实例成员的初始化
B. 构造方法
Bvar=2222
转自
http://www.blogjava.net/xiaodaoxiaodao/archive/2007/06/06/122383.html