• 静态域/域的初始化、静态代码块/构造代码块的实行、构造方法的调用 顺序


    这5者的先后顺序中,有些顺序是跟Java源代码顺序有关的,有些无关的。

    首先应该定义两个类,用于代表两种域的类型,这两个类的构造方法会打印信息,用于指示自身被实例化了。

    class Field {
        public Field(int i) {
            System.out.println("B: 域引用第 " + i + " 次实例化");
        }
    }
    
    class StaticField {
        public StaticField(int i) {
            System.out.println("A: 静态域引用第 " + i + " 次实例化");
        }
    }

    1:静态的“东西”一定是比非静态的先执行的。

    public class InitOrderTest {
        public static void main(String[] args) {
            Body b = new Body();
        }
    }
    
    class Body {
        // B
        {
            System.out.println("B: 构造代码块第1次");
        }
        Field f1 = new Field(1);
        {
            System.out.println("B: 构造代码块第2次");
        }
        {
            System.out.println("B: 构造代码块第3次");
        }
        Field f2 = new Field(2);
    
        // A
        static {
            System.out.println("A: 静态代码块第1次");
        }
        static StaticField sf1 = new StaticField(1);
        static {
            System.out.println("A: 静态代码块第2次");
        }
        static {
            System.out.println("A: 静态代码块第3次");
        }
        static StaticField sf2 = new StaticField(2);
    
        // C
        public Body() {
            System.out.println("C: 构造方法");
        }
    }
    A: 静态代码块第1次
    A: 静态域引用第 1 次实例化
    A: 静态代码块第2次
    A: 静态代码块第3次
    A: 静态域引用第 2 次实例化
    B: 构造代码块第1次
    B: 域引用第 1 次实例化
    B: 构造代码块第2次
    B: 构造代码块第3次
    B: 域引用第 2 次实例化
    C: 构造方法

    即便Body类的B代码片段写在A片段前面,打印结果A还是在B前面,因为类需要先加载才能实例化,静态域和静态代码块会在类生命周期的“初始化”步骤中进行处理。

    静态域和静态代码块算是“类"层次,域和构造代码块算是“对象”层次,同一层次的域和代码块顺序先后跟代码顺序一致,不存在一定是谁先处理的情况。

    class Body {
        // B
        {
            System.out.println("B: 构造代码块第1次");
        }
        {
            System.out.println("B: 构造代码块第2次");
        }
        Field f1 = new Field(1);
        {
            System.out.println("B: 构造代码块第3次");
        }
        Field f2 = new Field(2);
    
        // A
        static {
            System.out.println("A: 静态代码块第1次");
        }
        static {
            System.out.println("A: 静态代码块第2次");
        }
        static StaticField sf1 = new StaticField(1);
        static {
            System.out.println("A: 静态代码块第3次");
        }
        static StaticField sf2 = new StaticField(2);
    
        // C
        public Body() {
            System.out.println("C: 构造方法");
        }
    }
    A: 静态代码块第1次
    A: 静态代码块第2次
    A: 静态域引用第 1 次实例化
    A: 静态代码块第3次
    A: 静态域引用第 2 次实例化
    B: 构造代码块第1次
    B: 构造代码块第2次
    B: 域引用第 1 次实例化
    B: 构造代码块第3次
    B: 域引用第 2 次实例化
    C: 构造方法

    构造方法是这5者中最后执行的

    class Body {
        // C
        public Body() {
            System.out.println("C: 构造方法");
        }
    
        // B
        {
            System.out.println("B: 构造代码块第1次");
        }
        Field f1 = new Field(1);
        {
            System.out.println("B: 构造代码块第2次");
        }
        {
            System.out.println("B: 构造代码块第3次");
        }
        Field f2 = new Field(2);
    
        // A
        static {
            System.out.println("A: 静态代码块第1次");
        }
        static StaticField sf1 = new StaticField(1);
        static {
            System.out.println("A: 静态代码块第2次");
        }
        static {
            System.out.println("A: 静态代码块第3次");
        }
        static StaticField sf2 = new StaticField(2);
    }
    A: 静态代码块第1次
    A: 静态域引用第 1 次实例化
    A: 静态代码块第2次
    A: 静态代码块第3次
    A: 静态域引用第 2 次实例化
    B: 构造代码块第1次
    B: 域引用第 1 次实例化
    B: 构造代码块第2次
    B: 构造代码块第3次
    B: 域引用第 2 次实例化
    C: 构造方法
  • 相关阅读:
    RESTful API设计指南(转载)
    理解RESTful架构(转载)
    什么是FreeMaker?
    为了梦,向前冲!
    php时间输出结果减去一分钟
    利用css+js制作下拉列表
    zzz的口胡记
    UOJ507. 【JOISC2020】星座3(贪心)
    vim使用小记
    UOJ#62【UR #5】怎样跑得更快(反演)
  • 原文地址:https://www.cnblogs.com/deolin/p/7085903.html
Copyright © 2020-2023  润新知