public class Parent {
String name = "Parent";
Hello y = new Hello(name);
static{
System.out.println("Parents static method");
}
Parent(){
System.out.println("Parent Construct ");
}
}
class Child extends Parent{
String name = "Child";
Hello y = new Hello(name);
static{
System.out.println("Child static method");
}
Child(){
System.out.println("Child Construct");
}
public static void main(String[] args){
Child child = new Child();
}
}
class Hello{
Hello(String name){
System.out.println("Hello Construct From "+name);
}
}
Q:运行java Child 后的打印结果是什么?
A:
这题主要考查的两点:
- 类的加载过程
- 类对象创建过程
类的生命周期过程包含7个状态:加载,验证,准备,解析,初始化,使用,卸载。而本例中执行java Child指令,jvm将运行Child类入口静态方法main(),由于Child类此前未加载到内存中,所以必须执行类加载过程,加载Child class文件,因为Child 继承Parent类,根据java类加载规则,子类加载前先加载父类,连接并类初始化。类初始化实际上是执行类构造器<clinit>
方法的过程。<clinit>
方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块。所以前两条打印是Parent static method , Child static method
类加载完成后,main()方法中创建Child对象,jvm此时将调用Child对象构造方法。根据规则子类对象构造方法内必须先执行父类构造方法,同时类对象的成员变量赋值优先于类对象构造方法的执行。所以Hello y = new Hello(name) 会先于Parent,Child构造方法执行。分析完毕!