在许多传统语言中,程序是作为启动过程的一部分立刻被加载的。然后是初始化,紧接着程序开始运行,但是语言的初始化过程需要小心控制,确保static对象的初始化顺序对于程序有影响。在C++中一个static对象依赖另一个static的初始化就可能存在问题。
Java就不会出现这种问题,它采用一种不同的加载方式。Java中所有事物都是对象,每个类的编译代码都存在于它自己的独立的文件中,该文件只在需要使用其代码时才会被加载。可以说:“类的代码在初次使用时才被加载。”通常指加载发生在创建类的第一个对象时,但当访问static域或static方法时,也会发生加载。初次使用的过程也是static初始化的过程,所有的static对象和static方法等代码段都会在加载时按顺序依次初始化,static只能初始化依次。
class Insect{
private int i=9;
protected int j;
public Insect() {
// TODO Auto-generated constructor stub
System.out.println("i = "+i+" , j = "+j);
j=39;
}
private static int x1=printInit("Ineset.x1 initialized");
static int printInit(String s){
System.out.println(s);
return 47;
}
}
public class Beetle extends Insect{
private int k =printInit("Beetle.k initialized");
public Beetle(){
System.out.println("k= "+k);
System.out.println("j= "+j);
}
private static int x2=printInit("Beetle.x2 initialized");
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Beetle Constructor.");
Beetle beetle=new Beetle();
// Beetle beetle2=new Beetle();
}
}
output:
Ineset.x1 initialized
Beetle.x2 initialized
Beetle Constructor.
i = 9 , j = 0
Beetle.k initialized
k= 47
j= 39
/
运行Beetle.java程序时,第一是访问Beetle.main()(static方法)于是加载器开始启动并找出Beetle类的编译代码(Beetle.class),对它加载过程中,编译器发现它存在一个基类(extends关键词)于是它继续进行加载。不创建对象上述过程都要发生。如果该基类还有基类,第二个基类会被加载,如此类推。
以上就把必要的类都加载完成,对象就可以被创建了,对象中基本类型都会被设置成默认值,然后基类的构造器会被调用。本例中自动调用Insect构造器,然后实例变量和剩余构造被执行。