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

问题:

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)
Table
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard
f1(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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值