一个类中各种代码块的执行顺序

简介: 一个类中各种代码块的执行顺序

正文


01 只有父类的代码块


今天分享一点简单的技术,一起来分析一下一个类的代码块是什么顺序执行的。学习代码如下


public class MethodPrintSequenceTest {
    public static class Father {
        static {
            System.out.println("i am father's static block");
        }
        {
            System.out.println("i am father's normal block");
        }
        public Father() {
            System.out.println("i am father's Construction block");
        }
        static {
            System.out.println("i am father's another static block");
        }
        {
            System.out.println("i am father's another normal block");
        }
    }
    public static void main(String[] args) {
        Father f = new Father();
    }
}


在上面的代码中,我写了各种各样的代码块,看一下我们的执行结果。


i am father's static block
i am father's another static block
i am father's normal block
i am father's another normal block
i am father's Construction block
Process finished with exit code 0


显而易见,首先是静态代码块先执行,然后是普通的代码块后执行,最后才是构造方法,那么也就是说,在我们使用某一个对象的时候,对应的类已经把静态的普通的都已经执行了。

但是在执行的顺序上有什么特殊的地方呢?比例,都是静态代码块,为啥上面的先执行,下面的后执行,这就需要我们看一下编译后的代码啦!


28.png


经过IDEA的反编译,得到上面的反编译结果,显而易见,静态方法被合并了,而且是按照静态代码块的顺序合并的。同理,普通代码块放在了构造方法的最前面,顺序同静态代码块,这也就是,为啥他们的代码块是先执行的了。


02 父类与子类混合双打


上面执行的结果仅仅是某一个类的情况,那如果要是夹杂着继承关系,会是得到什么样的结果呢?一起看下面改造后的代码:


public class MethodPrintSequenceTest {
    public static class Father {
        static {
            System.out.println("i am father's static block");
        }
        {
            System.out.println("i am father's normal block");
        }
        public Father() {
            System.out.println("i am father's Construction block");
        }
        static {
            System.out.println("i am father's another static block");
        }
        {
            System.out.println("i am father's another normal block");
        }
    }
    public static class Sun extends Father {
        static {
            System.out.println("i am sun's static block");
        }
        {
            System.out.println("i am sun's normal block");
        }
        public Sun() {
            System.out.println("i am sun's Construction block");
        }
        static {
            System.out.println("i am sun's another static block");
        }
        {
            System.out.println("i am sun's another normal block");
        }
    }
    public static void main(String[] args) {
        Father f = new Sun();
    }
}

执行结果如下:


i am father's static block
i am father's another static block
i am sun's static block
i am sun's another static block
i am father's normal block
i am father's another normal block
i am father's Construction block
i am sun's normal block
i am sun's another normal block
i am sun's Construction block
Process finished with exit code 0


显而易见,执行的顺序分别是:执行父类的静态代码块->执行子类的静态代码块->执行父类的普通代码块和构造代码块->执行子类的普通代码块和构造代码块和我们平时认知是一样的。也就是,使用子类对象时候,首先要初始化父类的值,再初始化子类的值。反编译结果如下:


29.png

看上面的截图就显而易见了,怎么样的执行一目了然。


03 复盘


如何更加快速的知道怎么样的执行顺序,要牢记一点,就是先父类后子类,先静态后普通,最后才是构造。



相关文章
|
5月前
|
Java 编译器
Java中4种代码块:普通代码块,静态代码块,同步代码块,构造代码块
Java中4种代码块:普通代码块,静态代码块,同步代码块,构造代码块
222 0
实例详解局部代码块,构造代码块,静态代码块
实例详解局部代码块,构造代码块,静态代码块
|
Java
类成员(代码块)
类成员(代码块)
56 1
|
存储 C# C++
VS中的代码块的使用
VS中的代码块的使用
VS中的代码块的使用
|
Java 编译器
复习篇【类的构造方法与代码块的执行】
复习篇【类的构造方法与代码块的执行】
复习篇【类的构造方法与代码块的执行】
Xocde里面代码块的设置
Xocde里面代码块的设置
100 0
Xocde里面代码块的设置
|
架构师 Java Spring
静态代码块、静态变量,构造代码块、实例变量的执行顺序和继承逻辑(下)
静态代码块、静态变量,构造代码块、实例变量的执行顺序和继承逻辑(下)
静态代码块、静态变量,构造代码块、实例变量的执行顺序和继承逻辑(下)
|
Java 编译器 Spring
静态代码块、静态变量,构造代码块、实例变量的执行顺序和继承逻辑(上)
静态代码块、静态变量,构造代码块、实例变量的执行顺序和继承逻辑(上)