一个关于实例对象初始化的题

import java.io.PrintStream;

public class App
{
    private static App a = new App();
    //如果不实例化App,那么jvm也就不会加载SubClass类
    private SubClass t = new SubClass();
    static 
    {   
        System.out.println(3);
    }
    public App()
    {
        System.out.println(4);
    }
    public static void main(String args[])
    {
        System.out.println("main");
    }
}
class SuperClass{
    SuperClass(){
        System.out.println("Constructor SuperClass");
    }
}
class SubClass extends SuperClass{
    static{
        System.out.println(1);
    }
    public SubClass(){
        System.out.println(2);
    }
}

由以上代码分析类加载过程:
jvm首先加载App类进内存(由于存在main方法,jvm调用某个类的静态方法,那么这个类会被加载),然后按照声明的顺序给static成员分配内存空间.

private static App a = new App();
编译后实际情况是:
private static App a ;
static
{
   a = new App();  
   System.out.println(3);
}

而非static的字段初始化,是在构造器内部优先完成.也就是说:

private SubClass t = new SubClass();
编译后应该是:
private SubClass t;
public App()
{
    t = new SubClass();
    System.out.println(4);
}

程序执行static代码块时候,会先执行App类的空参构造器,然后会先创建SubClass实例对象(也可以理解成创建App类字节码对象需要依赖于SubClass字节码对象,如果找不到SubClass类,那么编译失败),此时,JVM需要加载SubClass类,发现extends关键字会优先加载SuperClass,并执行相应的static代码块,执行空参构造器创建SubClass实例对象,继续在App类中执行构造器,及static剩余代码.

程序输出:

1
Constructor SuperClass
2
4
3
main

以上分析,还望各位同仁不吝赐教.

你可能感兴趣的:(一个关于实例对象初始化的题)