JAVA对象的成员初始化顺序的初步理解

来源:互联网 发布:阿里巴巴国际淘宝网 编辑:程序博客网 时间:2024/05/18 02:18

问题:

JAVA创建一个对象的时候,静态成员和非静态是按什么顺序进行初始化的?


下面通过一个例子,如果你能准确地写出它的输出顺序,那么你对成员初始化顺序就有了一定的理解了.

然后在后面给出,为什么是这样的输出顺序?

class Bowl{public Bowl(int mark) {System.out.println("Bowl("+ mark +")");}void f1(int mark){System.out.println("f1("+ mark +")");}}class Table{static Bowl bowl1=new Bowl(1);public Table() {System.out.println("Table");bowl2.f1(1);}void f2(int mark){System.out.println("f2("+ mark +")");}static Bowl bowl2=new Bowl(2);}class Cupboard{Bowl bowl3=new Bowl(3);static Bowl bowl4=new Bowl(4);public Cupboard() {System.out.println("Cupboard");bowl4.f1(2);}void f3(int mark){System.out.println("f3("+ mark +")");}static Bowl bowl5=new Bowl(5);}public class StaticInitialization {public static void main(String[] args) {System.out.println("Creating new Cupboard() in main");new Cupboard();System.out.println("Creating new Cupboard() in main");new Cupboard();table.f2(1);cupboard.f3(1);}<pre name="code" class="java">static Table table =new Table();static Cupboard cupboard=new Cupboard();

}

建议自己先试着写一遍结果,然后对照真实输出结果

Bowl(1)Bowl(2)Tablef1(1)Bowl(4)Bowl(5)Bowl(3)Cupboardf1(2)Creating new Cupboard() in mainBowl(3)Cupboardf1(2)Creating new Cupboard() in mainBowl(3)Cupboardf1(2)f2(1)f3(1)


JAVA的初始化被分成几个部分(Murre murre 是类中的一个成员)

1静态成员指定初始化  和 静态块中初始化

静态成员指定初始化

static Murre murre=new Murre();

 

静态块中初始化

static{

murre = new Murre

}

这两者的优先级是相等的,意思按照书写顺序往下运行;

因此

static{son=2;<span></span>}static int son=1;

int son=1;{son=2;}

这两者的结果是有区别的(我之前有些误会)


2非静态成员指定初始化 和非静态块初始化


非静态成员指定初始化

Murre murre=new Murre();


非静态块初始化

Murre murre;

{

murre=new Murre();

}

优先级是相等的,按照书写顺序,同上静态


3构造函数中的初始化

Murre murre1;

static Murre murre2;

public Shit(Murre mu,Murre mu2)  //Shit类的构造函数

{

muure1=mu;

murre2=mu2;

}


创建一个类的初始化顺序就是按照我写的3种初始化顺序初始化的,

JAVA如此设计的根本原因是:

确保,每一个变量在被使用之前,都能被好好地初始化.


回到刚才的程序中,让我们分析一波:

首先要调用Class StaticInitialization 的static main()函数,所以加载StaticInitialization中的static 成员

 也就是

static Table table =new Table(); <span style="white-space:pre"></span><span style="font-family: Arial, Helvetica, sans-serif;">//静态指定初始化</span>static Cupboard cupboard=new Cupboard();
这两个,先看第一个

由于涉及到了new Table();

所以又要加载Table类,在Table类中要执行的初始化有:

static Bowl bowl1=new Bowl(1);<span style="white-space:pre"></span><span style="font-family: Arial, Helvetica, sans-serif;">//静态指定初始化  </span><span style="white-space:pre"></span>public Table() {System.out.println("Table");<span style="white-space:pre"></span>//构造器初始化bowl2.f1(1);}static Bowl bowl2=new Bowl(2);<span style="white-space:pre"></span><span style="font-family: Arial, Helvetica, sans-serif;">//静态指定初始化</span>
其中构造器初始化要慢于所有的静态初始化,即使有一个静态初始在它的后面

这里又涉及到新建Bowl对象

所以又要初始化Bowl对象,所以又要初始化Bowl的初始化

public Bowl(int mark) {System.out.println("Bowl("+ mark +")");}

到这里,应该可以明白为什么输出顺序是这样子了,剩下的自行推导..



0 0