Java 静态代码块、构造代码块、构造函数的执行顺序,可能颠覆你的认知

376 阅读2分钟

静态代码块:在java类中使用 static{} 包裹的代码。类加载时执行,只会执行一次。注意:静态代码块和静态属性初始化调用的优先级一样,如果有多个静态代码块和多个静态比阿尼朗初始化,则按它们定义的顺序调用。

构造代码块:在java类中使用 {} 包括的代码,没调用一次就会执行一次。注意:构造代码块和普通属性初始化的优先级一样,如果有多个构造代码块和多个普通属性的初始化,则按它们定义顺序调用。

构造函数:主要功能是用来在创建对象时初始化对象,也可以给属性初始值。没调用一次就会执行一次。

Java类中三个自调用的函数,除了构造函数具有方法体,其他两个为什么也称之为函数呢?留给你去查询。

优先级:

非继承:静态代码块-》构造代码块--》构造函数

继承:父类静态代码块-》子类静态代码块-》父类构造代码块-》父类构造函数-》子类构造代码块-》子类构造函数

静态语句块中只能访问定义在静态语句块之前的变量,定义在它之后的变量,在前面的语句块中可以赋值,但是不能访问。

针对可以赋值,但不能访问的问题?我们可以查看编译后的class文件,其实在class开头会有静态变量的定义,请注意只有定义而没有初始化,因此可以进行赋值,但为什么不能访问呢?这就涉及到变量未初始化不能访问的问题。

经过编译之后,静态代码块会按顺序合并为一个 static{} 静态代码块内。

构造代码块会合并至构造函数之前。

这也就解释了为什么构造代码块会看起来在构造函数之前执行。


image.png 但如果包含了多个构造函数呢?

如果构造函数之前没有调用关系,那么在每个构造函数前面都会插入构造代码块的代码。

image.png

不禁要问,这样子的话,我如果构造函数之间存在调用,那么构造代码块就重复执行了呢?答案是这样吗?

如果存在了this() 构造函数之前的调用,那么当前构造函数之前不会插入构造代码块。

image.png