[java] 类变量初始化顺序

前言

 本博客旨在深入了解类变量的初始化,如果有分析错误的地方,希望得到各位大牛的指正.

类成员变量

类的成员变量分为两种: 普通成员变量 和 静态成员变量 

  •  普通成员变量 :它被存储在 堆内存 中,每个对象都有自己的一个变量
  •  静态成员变量 :使用 static 关键词修饰的成员变量,它被存储在 静态方法区 ,该类的所有对象都共享这个变量

成员变量的初始化

类的成员变量初始化地点有三处:

  • 声明时初始化
  • 代码块中初始化
  • 构造器中初始化

成员变量初始化顺序

成员变量初始化顺序

让我们来看下面的一段代码:

CommonMemberVariableTest.java:

public class CommonMemberVariableTest {
    public static void main(String ...agrs) {
        CommonMemberVariable commonMemberVariable = new CommonMemberVariable();
    }
}

class ParentCommonMemberVariable {
    private Variable1 parentVariable1 = new Variable1("parent v1 statement");
    private Variable1 parentVariable2 = new Variable1("parent v2 statement");

    private static Variable1 parentStaticVariable1 = new Variable1("static parent v1 statement");
    private static Variable1 parentStaticVariable2 = new Variable1("static parent v2 statement");

    {
        parentVariable1 = new Variable1("parent v1 code block");
    }

    static {
        parentStaticVariable1 = new Variable1("static parent v1 code block");
    }

    public ParentCommonMemberVariable() {
        parentVariable1 = new Variable1("parent v1 constructor");
    }
}

class CommonMemberVariable extends ParentCommonMemberVariable {
    private Variable1 variable1 = new Variable1("v1 statement");
    private Variable1 variable2 = new Variable1("v2 statement");
    private static Variable1 staticVariable1 = new Variable1("static v1 statement");
    private static Variable1 staticVariable2 = new Variable1("static v2 statement");


    {
        variable1 = new Variable1("v1 code block");
    }

    static {
        staticVariable1 = new Variable1("static v1 code block");
    }

    public CommonMemberVariable() {
        variable1 = new  Variable1("v1 constructor");
    }
}

class Variable1 {
    public Variable1(String info) {
        System.out.println(info);
    }

上面代码的执行结果如下:


static parent v1 statement
static parent v2 statement
static parent v1 code block
static v1 statement
static v2 statement
static v1 code block
parent v1 statement
parent v2 statement
parent v1 code block
parent v1 constructor
v1 statement
v2 statement
v1 code block
v1 constructor 

结论:

  •  当我们只看 variable1 这个成员变量时,从打印可以发现,普通成员变量的初始化执行顺序是 声明时初始化 -> 代码块中初始化 ->构造器中初始化 
  • 当我们的类种有多个普通成员变量时,那么多个普通成员变量的初始化顺序是按照从上往下的顺序进行初始化
  • 如果我们只看子类或者父类的普通成员变量和静态成员变量,则会发现静态成员变量的初始化要先于普通成员变量,并且静态成员变量的初始化于普通成员变量的初始化顺序保持一致
  • 当我们的类种有继承关系时,那初始化的顺序为 父类静态变量声明时 -> 父类静态代码块 -> 子类静态变量声明时 -> 子类静态代码块 -> 父类普通成员变量声明时 -> 父类代码块 -> 父类构造器 -> 子类普通成员变量声明时 -> 子类代码块 -> 子类构造器 
原文地址:https://www.cnblogs.com/cafebabe-yun/p/11499080.html