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

来源:互联网 发布:资金流向分析软件 编辑:程序博客网 时间:2024/05/18 07:14

作者: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 stubSystem.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.在类的内部域的初始化是最先进行的,然后才调用构造函数。


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







1 0