日期:2014-05-20 浏览次数:20865 次
class A { {System.out.println("1");} //初始化块 public A() { System.out.println("2"); } } public class B extends A { {System.out.println("3");} //初始化块 public B () { System.out.println("4"); } public static void main(String[] args) { new B(); } }
------解决方案--------------------
继承的实例类加载器的执行过程如下:
1. ClassLoader加载Son这个类.
2. 准备调用Son的构造方法.
3. 准备调用Son的父类Father的构造方法.
4. 准备调用Father的父类java.lang.Object的构造方法.
5. 执行java.lang.Object的构造方法.
6. 初始化Father类的成员变量
7. 执行Father的构造方法,
8. 初始化Son的成员变量
9. 执行Son的构造方法
------解决方案--------------------
为什么有1与5这两个步骤?因为在构造方法执行前要初始化成员变量.
从9到6再到2,好像没有进入构造方法内部,这样子调用起什么作用,因为在子类的构造方法Son()里面第一行,默认是调用父类的空构造方法super(),只是隐式调用而已.
------解决方案--------------------
继承的实例类加载器的执行过程如下:
1. ClassLoader加载Son这个类. ---因为Test是启动类 ,所以jvm会先加载Test类,执行main方法 9
2. 准备调用Son的构造方法. 3. 准备调用Son的父类Father的构造方法.
4. 准备调用Father的父类java.lang.Object的构造方法.
5. 执行java.lang.Object的构造方法.
6. 初始化Father类的成员变量
7. 执行Father的构造……
---因为Test是启动类 ,所以jvm会先加载Test类,执行main方法 9
---创建Son对象 ,所以 6
---由于Son继承自 Father,所以在进入Son构造方法时 ,会先调用父类的构造方法 ,完成父类中定义的变量初始化 ,否则子类无法使用父类中的属性方法 2
---初始化一个类时(指的是创建一个类的对象,不是类加载),会先执行为非静态变量分配内存 ,执行顺序为非静态变量在类中定义的顺序 ,执行非静态代码块 即{}中的代码 ;所以 1
---执行完非静态变量分配内存及初始化值后,接着执行 构造函数中的代码 3 4
---完成父类的初始化后 ,接着执行Son构造方法,在执行之前类似于父类初始化 ,先初始化非静态变量分配内存,执行非静态代码块 5
---然后执行Son构造函数体 7 8
9-6-2-1-3-4-5-7 -8