Java中静态变量和非静态变量的初始化顺序

 

先看下面的程序:

package c05.net;

class Bowl {
Bowl(int marker) {
System.out.println("Bowl(" + marker + ")");
}

void f1() {
System.out.println("Ok");
}
}

class Cupboard {
Bowl b1 = new Bowl(1);

static Bowl b2 = new Bowl(2);

Cupboard() {
System.out.println("Cupboard()");
}

static Bowl b3 = new Bowl(3);
}

class Table {
Table() {
System.out.println("Table()");
}
Table(String a,int i){
this();
System.out.println("Ok");
}
}

public class Order {
static Cupboard t1 = new Cupboard();

static Table t2;

Bowl t3 = new Bowl(10);

void print() {
t3.f1();
}

public static void main(String[] args) {
System.out.println("Creating new Cupboard() in main");
new Cupboard();
System.out.println("Creating new Cupboard() in main");
Order od = new Order();
od.t3.f1();
Table t4 = new Table("aa",1);
}
}

运行结果:

Bowl(2)
Bowl(3)
Bowl(1)
Cupboard()
Creating new Cupboard() in main
Bowl(1)
Cupboard()
Creating new Cupboard() in main
Bowl(10)
Ok
Table()
Ok

分析:首先程序从public类开始,装载Order,class,运行static Cupboard t1 = new Cupboard();

由于t1是一个对象引用变量,首先得到初始化,然后转到Cupboard类的实例中,这时候程序开始初始化

该实例中的变量,按照先static后非static变量初始化的顺序原则开始初始化各个变量,此时,

static Bowl b2 = new Bowl(2);

static Bowl b3 = new Bowl(3);

这两块先得到初始化

然后    Bowl b1 = new Bowl(1);得到初始化(注意,这是非stataic变量)

然后转到Cupboard() 构造函数。

此时Cupboard类已经初始化完毕,程序返回到public类中,又发现有 static Table t2;

开始初始化,由于t2只是个声明的变量,并没有创建一个Table对象让它指向,因此不要管这个t2变量。

在public类中,由于此时再没有static变量可以初始化,那么程序转到static方法main中进行,

(注意:Bowl t3 = new Bowl(10); 这一句为什么得不到初始化,是因为此时没有创建类Order的实例,所以程序目前还不会初始化该代码,至于以后会不会初始化,还要看在main方法中是否会创建Order类的实例,如创建了,则一定初始化,否则不会。)

在main方法中,

System.out.println("Creating new Cupboard() in main");//首先打印该行要输出的语句

new Cupboard();   //创建了Cupboard类的实例,程序转到Cupboard中进行变量初始化,此时要注意:    

static变量的初始化,它只能初始化一次,也就是说,如果前面已经初始化过了,那么此时就不必要再初

始化了,这一点要牢记!!!


System.out.println("Creating new Order() in main");//程序转入此行打印要输出的语句

Order od = new Order();//创建Order对象实例,程序转入实例od中,此时Bowl t3 = new Bowl(10);

这一句的t3会得到初始化,程序转到Bowl类中进行有关的操作,操作完后返回到main方法中

od.t3.f1();   //调用实例t3中的方法f()

Table t4 = new Table("aa",1); //创建Table类的实例,让t4指向这个实例,t4得到初始化,调用Table含

有参数的构造方法,程序进行下去。

 

这样就完成了对这个程序的真个的流程的分析,如果有错误的地方,或者还要补充的地方,还希望大家

指点一下,谢谢!!!

最后再总结一下:

初始化顺序是:

(1) 先是父类的static变量和static初始化块

(2)然后是子类的static变量和static初始化块  

(3)父类的实例变量、初始化快

(4)父类的构造方法

(5)子类的实例变量、初始化快

(6)子类构造方法

 

 

 

你可能感兴趣的:(Java)