一个程序带你了解java初始化

作者:faaronzheng 转载请注明出处!

下面一段java代码我认为能较完整的展现java初始化过程。

class MyPrint
{
	MyPrint(int i)
	{
		System.out.println("MyPrint"+i);
	}
}

class Init
{
	class Inner
	{                                                                                                                            
		Inner()
		{
			System.out.println("innerclass");
		}                                                                                                 
	}
	Init()
	{
		System.out.println("baseClass");
	}
	static MyPrint p1=new MyPrint(1);
	MyPrint p=new MyPrint(2);
	
}
class Init1 extends Init
{
	MyPrint p=new MyPrint(3);
	static MyPrint p1=new MyPrint(4);
	public Init1() 
	{
	    System.out.println("extendClass");
	}

}


public class InitOrder {
	Init1 init1=new Init1();                 //和下面一句位置交换一下就会有区别        
	Init init=new Init();  
//	Init.Inner in=init.new Inner();
	static MyPrint p1=new MyPrint(5);
	InitOrder()
	{
		System.out.println("GouZao");
	}
	MyPrint p=new MyPrint(6);

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("hello");
		InitOrder io=new InitOrder();
	}
//	static Init i=new Init();
}


在解释初始化过程前首先说明下列几个问题

1.类加载完后,对象才可以创建。

2.加载类主要就是对静态成员变量和方法进行初始化。

3. 静态域只会初始化一次。


这段代码的执行结果是什么呢?

首先,java编译器会寻找到程序的入口点mian()。要执行main()方法(静态),必须要加载InitOrder类。类中静态域会最先初始化,所以首先会打印一个MyPrint5。之后调用main()方法,打印一个hello,接下来执行

InitOrder io=new InitOrder();
创建io对象(InitOrder类已加载), 类内部域的初始化是最先进行的,然后才调用构造函数。所以会执行
Init1 init1=new Init1();
创建init1对象(这时Init1还未加载),并且Init1是继承自Init的,我们要知道 存在继承关系的情况下,会先加载基类。所以会先初始化根基类中的静态域,接下来初始化导出类中的静态域。结果会先打印MyPrint1,再打印MyPrint4。类加载完毕后,对象就可以被创建了。因为 存在继承关系,所以会先初始化基类,打印出MyPrint2和baseClass。 基类初始化完后,就会初始化导出类,所以会打印MyPrint3和extendClass。至此,init1对象创建并初始化完了。然后执行
Init init=new Init(); 
创建init对象(这时Init已加载)因为静态域只会初始化一次,所以打印MyPrint2和baseClass。接下来执行
MyPrint p=new MyPrint(6);
打印MyPrint6。最后调用InitOrder类的构造函数打印GouZao。至此,io对象创建并初始化完毕。一个完整的初始化过程结束了。这时你会发现程序中还有一个注释和两条被注释掉的语句。
Init1 init1=new Init1();                         //和下面一句位置交换一下就会有区别
Init init=new Init();  
交换位置后主要的变化在于先执行
Init init=new Init(); 
时不会打印MyPrint4。主要想表明加载类时才会对静态成员变量和方法进行初始化,显然这里不会加载Init1。

至于第一条被注释掉的语句只想说明内部类并不是外围类的域,内部类也只有创建对象时才会初始化。至于第二条被注释的语句,相信你了解了前面的内容后也可以知道答案。


最后总结几条原则:

1.只要类被加载,静态域一定最先初始化。

2.存在继承关系的情况下,先加载基类,在加载导出类。

3.初始化对象时,先初始化基类,在初始化导出类。

4.在类的内部域的初始化是最先进行的,然后才调用构造函数。


所学有限,如有错误,欢迎指正。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值