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
以上分析,还望各位同仁不吝赐教.
网友评论