当初始化类自身的时候,首先会初始化其父类,这是一个递归的过程,直到Object类为止。
测试程序如下
package test1026;
class Animal {
static{
System.out.println("执行Animal类的静态初始化块!");
}
public Animal() {
System.out.println("执行Animal无参构造方法!");
}
{
System.out.println("执行Animal初始化块!");
}
private int life = getLife();
private static String name = getName();
public static int getLife() {
System.out.println("初始化Animal类中的实例变量life");
return 10;
}
public static String getName() {
System.out.println("初始化Animal类中静态变量name");
return "Animal";
}
}
class Cat extends Animal {
private static String name = getName();
private int life = getLife();
{
System.out.println("执行Cat初始化块~");
}
static{
System.out.println("执行Cat类的静态初始化块");
}
public static int getLife() {
System.out.println("初始化Cat类的实例变量");
return 15;
}
public static String getName() {
System.out.println("初始化Cat类的静态变量name");
return "Cat";
}
public Cat() {
System.out.println("执行Cat构造器!");
}
}
class WildCat extends Cat{
public WildCat() {
System.out.println("执行WildCat类的构造器");
}
private int life = getLife();
{
System.out.println("执行WildCat的初始化块");
}
static{
System.out.println("执行WildCat的静态初始化块");
}
public static int getLife() {
System.out.println("初始化WildCat类的实例变量");
return 20;
}
public static String getString() {
System.out.println("初始化WildCat类的静态变量");
return "WildCat";
}
private static String name = getName();
}
public class IntOrder {
WildCat wildcat = new WildCat();
static{
System.out.println("执行IntOrder的静态初始化块");
}
public static void main(String[] args) {
System.out.println("执行Main()方法!!!!!!");
WildCat wildcat = new WildCat();
System.out.println();
System.out.println("第二次创建一个对象-----------------------------静态不再执行!");
WildCat wildcat1 = new WildCat();
}
}
执行结果如下:
执行IntOrder的静态初始化块
执行Main()方法!!!!!!
执行Animal类的静态初始化块!
初始化Animal类中静态变量name
初始化Cat类的静态变量name
执行Cat类的静态初始化块
执行WildCat的静态初始化块
初始化Cat类的静态变量name
执行Animal初始化块!
初始化Animal类中的实例变量life
执行Animal无参构造方法!
初始化Cat类的实例变量
执行Cat初始化块~
执行Cat构造器!
初始化WildCat类的实例变量
执行WildCat的初始化块
执行WildCat类的构造器
第二次创建一个对象-----------------------------
执行Animal初始化块!
初始化Animal类中的实例变量life
执行Animal无参构造方法!
初始化Cat类的实例变量
执行Cat初始化块~
执行Cat构造器!
初始化WildCat类的实例变量
执行WildCat的初始化块
执行WildCat类的构造器
从运行结果我们可以分析出,在考虑到父类的情况下,类的初始化顺序如下:
(1)当类第一次使用时,JVM就会加载该类,如果该类存在父类,那么就会首先加载父类,这是一个递归的过程,直到Object类为止。在类的加载中,首先将静态成员变量按照默认值初始化,然后按照在类中声明的顺序执行静态初始化块和静态成员变量显示的初始化。这个过程是从父类到子类,并且只执行一次。
(2)当父类与子类的静态代码初始化完毕,如果创建了类的对象,在初始化子类之前,会首先对父类的实例变量按照默认值初始化,然后按照在类中的声明顺序中执行初始化块和实例变量显示的初始化,然后调用父类的构造器,这也是一个递归的过程,直到Object类为止。此过程在每次创建对象时都会执行,如果没有创建任何对象,本环节就不会执行。例如IntOrder类的第一行,因为我们没有创建IntOrder对象,所以对象的实例变量就得不到初始化。
在本程序中,由于我们执行的是IntOrder类,所以首先加载其类的静态初始块,然后调用该类的main方法,接下来创建了WildCat类的对象,因为是第一次使用此类,便按照上面叙述的顺序进行,虽然程序中创建了两个WildCat类的对象,但是静态的初始化代码只执行一次。
(以下为摘录于他人)
Java初始化顺序如图:
类的生命周期,将经历类的装载,链接,初始化,使用,卸载. 装载是将字节码读入到内存的方法区中, 而类的初始化则会在线程栈中执行static{}块的code. 在之前,这个块有另一个名字<cinit>即类初始化方法.现在改名为static{}了. 类的初始化只进行一次. 但是,每当一个类在装载和链接完毕以后,通过字节码的分析,JVM解析器已经知道B是继承A的,于是在初始化B类前,A类会先初始化.这是一个递归过程.