现在这样一个问题,不明白想请会的讲解下,问题如下:
现有三个类: 一个Father类,一个Son类,继承Father类,一个测试类Test,代码如下:
public class Father {
public int value=100;             // 这里为1
public Father(){                  // 这里为2
int i=20;                // 这里为3
System.out.println(i);   // 这里为4
}
}public class Son extends Father {
public int id=200;                  // 这里为5
public Son(){                       // 这里为6
int j=10;           // 这里为7
System.out.println(j);     // 这里为8
}
}public class Test{
    public static void main(String[] args){
        Father f=new Son();                   // 这里为9
    }
}现在我在Test中的主方法main那里设置断点:用debug as 调试,只按F5,
我想问下为什么执行顺序会是:9→6→2→1→3→4→5→7→8→9
请各位大神级人物讲解下,尤其为什么有1与5这两个步骤,还有从9到6再到2,好像没有进入构造方法内部,这样子调用起什么作用,或者有什么含义?

解决方案 »

  1.   

    6和2表示生成对象需要调用构造方法,6->2的顺序表示调用子类构造方法之前会先跳转去调用父类的构造方法
    1和5表示在构造方法执行之前会先执行初始化块处理
    int value = 100;
    相当于
    int  value;
    {value = 100;} //初始化块给LZ个例子
    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();
        }
      

  2.   

    继承的实例类加载器的执行过程如下:
    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的构造方法
     
      

  3.   

    为什么有1与5这两个步骤?因为在构造方法执行前要初始化成员变量.从9到6再到2,好像没有进入构造方法内部,这样子调用起什么作用,因为在子类的构造方法Son()里面第一行,默认是调用父类的空构造方法super(),只是隐式调用而已. 
      

  4.   

    继承的实例类加载器的执行过程如下:
    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