Java 类的加载和初始化

时间:2023-02-16 22:31:17


public class Insect {
    private int i = 9;
    protected int j;
    Insect() {
    System.out.println("i = " + i +", j = " + j);
    j = 39;
    }
    private static int x1 = 
    printInit("static Insect.x1 initialized");
protected static int printInit(String string) {
// TODO Auto-generated method stub
System.out.println(string);
return 47;
}
    

}


public class Beetle extends Insect {
    private int k = printInit("Beetle.k initalized");
    public Beetle() {
        System.out.println("k = " + k);
        System.out.println("j = " + j);
    }
    private static int x2 =
        printInit("static Beele.x2 initialized");
    public static void main(String[] args) {
    System.out.println("Beetle constructor");
    Beetle b = new Beetle();
    }
}


上面的输出结果为

static Insect.x1 initialized
static Beele.x2 initialized
Beetle constructor
i = 9, j = 0
Beetle.k initalized
k = 47
j = 39

而将Beetle b = new Beetle()这句注掉输出结果为

static Insect.x1 initialized
static Beele.x2 initialized
Beetle constructor

对比以上结果则类的加载和初始化规律为

1.加载类的时候并不会初始化非静态代码,实例化的时候才会初始化非静态代码。

2.类是在任何static成员被访问时加载的。

   一般情况加载发生在创建类的第一个实例,由于构造器也是static方法,也是符合这个规律的。

   加载时会先初始化父类static变量,再初始化子类static变量,static变量只会被初始化一次。

如本例,Beetle在运行时,试图访问Beetle.main,于是开始找出Beetle类进行加载。 

3.在new 一个类的实例的时候会按照如下顺序初始化:

    父类非静态变量/代码块->父类构造函数->子类非静态变量/代码块->子类构造函数。