代码如下,从书上截得,
package chapter8;import chapter8.Lunch.PortableLunch;class Meal {
Meal(){
System.out.println("Meal()");
}
}class Bread {
Bread(){
System.out.println("Bread()");
}
}class Lunch extends Meal {
Lunch (){
System.out.println("Lunch ()");
}class PortableLunch extends Lunch {
      PortableLunch() {
       System.out.println("PortableLunch()");
      }
}
}public class Sandwich extends PortableLunch{
    private Bread b = new Bread(); 
    private Sandwich(){System.out.println("Sandwich()");}
public static void main(String[] args) {
new Sandwich();
}}请高手解释下,这个初始化顺序, 构造器-->成员变量-->导出类的构造主体
JVM 这样 实现的原理是什么? 小弟在此谢过!!

解决方案 »

  1.   

    首先程序的入口是main函数,在创建对象的时候,会调用构造函数,而且是优先调用其最顶级父类的构造函数,然后依次向下调用,在调用的过程中所涉及到的类会被加载,类加载的过程中类的成员变量以及静态变量静态属性进行初始化!其他的属性在不会被加载,只有在第一次使用的时候才会起作用!
    所以该程序应该是首先调用PortableLunch的构造并加载这个类,然后调用 Sandwich 的构造,在调用 Sandwich 的构造的时候 Sandwich 类会被加载,既初始化private Bread b ,所以执行System.out.println("Bread()",然后执行 System.out.println("Sandwich()")
    以上,参照Thinking in Java
      

  2.   

    实类化的时候(调用构造方法),如果有继承先实列父类,如果父类还有爷爷类,就先实列化爷爷类,再实类化父类,继承关系是这样子.祖先类的方法或属性,子类都可以用(私有修饰private的方法或属性列外)
      

  3.   

    1,应该是先初始化静态成员变量,因为客户程序可能不构造你的实例而access静态成员变量.2,父类的构造函数,因为子类可能要access父类的东西.
    比如:
    在PortableLunch里加上 protected String str = null;
    在PortableLunch()里加上  str = "str";
    在Sandwich 里加上private String s = this.str;
    所以要先构造父类,子类就可以安全地访问父类的成员.3,当前类的成员变量,因为本身类的构造函数可能访问成员变量.4,执行构造函数体.
      

  4.   

    1,应该是先初始化静态成员变量,因为客户程序可能不构造你的实例而access静态成员变量.2,父类的构造函数,因为子类可能要access父类的东西.
    比如:
    在PortableLunch里加上 protected String str = null;
    在PortableLunch()里加上  str = "str";
    在Sandwich 里加上private String s = this.str;
    所以要先构造父类,子类就可以安全地访问父类的成员.3,当前类的成员变量,因为本身类的构造函数可能访问成员变量.4,执行构造函数体.