Java中全局变量初始化顺序

  • 首先,在加载类或者创建类的第一个对象的时候,初始化静态变量。但是无论创建多少个对象,静态变量只初始化一次。
  • 然后,初始化非静态变量。如果非静态变量在声明的位置没有初始化,则编译器为基本类型数据赋值0,对象引用赋值为null。
  • 最后,是调用构造器初始化。

下面通过代码并结合继承详细解释:

class Insect {
    private int m = printInit("Insect.m initialized");
    private int i = 9;
    protected int j;
    
    Insect() {
        System.out.println("i = " + i + "; j = " + j);
        j = 39;
    }
    
    static int printInit(String s) {
        System.out.println(s);
        return 47;
    }
    
    private static int x1 = printInit("static Insect.x1 initialized"); 
}

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

// output:
// 	static Insect.x1 initialized
// 	static Beetle.x2 initialized
// 	Beelte constructor
// 	Insect.m initialized
// 	i = 9; j = 0
// 	Beelte.k initialized
// 	k = 47
// 	j = 39

  • 1.加载类。在运行这段代码时,所发生的第一件事情就是试图访问Beetle.main()。于是加载器开始启动并找出Beetle类的编译代码。在对它进行加载的过程中,编译器注意到它有一个父类,于是先去加载父类。加载父类,初始化静态变量x1。加载父类完毕后再加载子类,初始化静态变量x2。这种初始化顺序是合理的,因为子类的的初始化可能会依赖于父类的初始化。
  • 2.访问main方法。
  • 3.试图创建Beetle对象,因为Beetle类继承自Inspect类,所以在创建Beetle对象之前,会先创建Inspect对象。这是通过在构造器中隐式的使用super关键字实现的,当然你也可以在子类的构造器中显示使用super的调用父类构造器,但是这并不会带来什么额外的效用。
  • 4.创建父类Inspect对象。先初始化全局变量(无论全局变量的位置在哪儿,都会在构造器被调用之前完成初始化),然后再调用构造器初始化。
  • 5.创建子类Beetle对象。同父类初始化顺序一样,也是先初始化全局变量,再调用构造器初始化。

猜你喜欢

转载自blog.csdn.net/weixin_34850743/article/details/87985818