Java类初始化顺序

Java程序在它运行之前,并非完全加载,其各个部分是在必需时才加载。Java类的初始化顺序,是先静态对象,而后是非静态对象。类加载器加载class文件时,初始化静态对象。new操作符时,初始化非静态对象。

在类的内部,变量定义的先后决定了初始化的顺序。即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造方法)被调用之前得到初始化。


1.无继承类初始化

public class Client {


    public static class Person {
        public Person(String str) {
            System.out.println(str);
        }
    }

    public static class Test {

        //静态成员变量 A
        public static Person sPersonA = new Person("A 静态成员变量初始化");

        //静态初始化代码块 B
        static {
            System.out.println("B 静态初始化块");
        }

        //成员变量 C
        public Person mPersonC = new Person("C 成员变量初始化");

        //初始化代码 D
        {
            System.out.println("D 初始化代码块");
        }

        //构造函数 E
        public Test() {
            System.out.println("E 构造函数");
        }


        //静态成员变量 F
        public static Person sPersonF = new Person("F 静态成员变量初始化");

        //静态初始化代码块 G
        static {
            System.out.println("G 静态初始化块");
        }

        //成员变量 H
        public Person mPersonH = new Person("H 成员变量初始化");

        //初始化代码 I
        {
            System.out.println("I 初始化代码块");
        }


    }

    public static void main(String[] args) {
        Test test = new Test();
    }

    }

运行结果如下:

A 静态成员变量初始化
B 静态初始化块
F 静态成员变量初始化
G 静态初始化块
C 成员变量初始化
D 初始化代码块
H 成员变量初始化
I 初始化代码块
E 构造函数

由此可以得出以下结论:

初始化顺序: 静态变量/静态代码块 -> 成员变量/代码块 -> 构造函数
其中,静态变量与静态代码块,成员变量与代码块的初始化顺序只取决于定义顺序。

Created with Raphaël 2.1.0 Start 静态变量/静态代码块 成员变量/代码块 构造函数 End

2. 子类初始化顺序

创建一个TestSub类继承Test类,

public static class TestSub extends Test {

    //静态成员变量 a
    public static Person sPersonA = new Person("a 静态成员变量初始化");

    //静态初始化代码块 b
    static {
        System.out.println("b 静态初始化块");
    }

    //成员变量 c
    public Person mPersonC = new Person("c 成员变量初始化");

    //初始化代码 d
    {
        System.out.println("d 初始化代码块");
    }

    //构造函数 e
    public TestSub() {
        System.out.println("e 构造函数");
    }


    //静态成员变量 f
    public static Person sPersonF = new Person("f 静态成员变量初始化");

    //静态初始化代码块 g
    static {
        System.out.println("g 静态初始化块");
    }

    //成员变量 h
    public Person mPersonH = new Person("h 成员变量初始化");

    //初始化代码 i
    {
        System.out.println("i 初始化代码块");
    }

}


public static void main(String[] args) {
    //Test test = new Test();
    TestSub sub = new TestSub();
}

运行结果如下:

A 静态成员变量初始化
B 静态初始化块
F 静态成员变量初始化
G 静态初始化块
a 静态成员变量初始化
b 静态初始化块
f 静态成员变量初始化
g 静态初始化块
C 成员变量初始化
D 初始化代码块
H 成员变量初始化
I 初始化代码块
E 构造函数
c 成员变量初始化
d 初始化代码块
h 成员变量初始化
i 初始化代码块
e 构造函数

由此可以得出以下结论:

子类初始化顺序:
父类静态变量/父类静态方法块 -> 子类静态变量/子类静态方法块 -> 父类成员变量/方法块 -> 父类构造函数 -> 子类成员变量/方法块 -> 子类构造函数

Created with Raphaël 2.1.0 Start 父类静态变量/父类静态方法块 子类静态变量/子类静态方法块 父类成员变量/方法块 父类构造函数 子类成员变量/方法块 子类构造函数 End
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值