类的初始化

Posted miaooooo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类的初始化相关的知识,希望对你有一定的参考价值。

类的初始化时类加载的最后一步,此时才开始执行 Java 代码(字节码)。

初始化阶段是开始执行 clinit<>() 方法的过程。

clinit<>():由编译器收集类中的类变量赋值操作和 static 代码块中的语句合并产生的,收集顺序与源文件中出现的顺序决定;static 语句块只能访问到在 static 语句块之前定义的变量,定义在static 语句块之后的变量,static 语句块只能赋值,不能访问(编译器会提示:Inlegal forward reference)。

补充(来自 stack overflow ):

init() 和 clinit<>() 区别:

init():实例构造函数(构造函数之一),非静态字段的初始化;

clinit<>():静态字段、静态代码块的初始化。

虚拟机会保证在子类的 clinit<>() 方法之前,父类的 clinit<>() 方法已经执行完毕,所以虚拟机中第一个执行 clinit<>() 方法的类一定是 java.lang.Object。

父类的 clinit<>() 方法优先于子类的 clinit<>() 方法,则父类的静态语句块优先于子类的变量赋值操作。

<clinit>():对于类或接口来说不是必须的,如果一个类中没有静态语句块,也没有对变量的赋值操作,编译器可以不为这个类生成 <clinit>() 方法。

接口中不能使用静态语句块,但仍有变量初始化的赋值操作,接口也会生成 <clinit>() 方法,接口与类不同的是,执行接口的 <clinit>() 方法不需要先执行父接口的 <clinit>() 方法,只有当使用父接口中定义的变量时,父接口才会初始化,接口中实现的类在初始化时也不会执行接口的 <clinit>() 方法。

以上是关于类的初始化的主要内容,如果未能解决你的问题,请参考以下文章

为啥不能在派生类的构造函数初始化列表中初始化基类的数据成员?

java类的初始化顺序

类的加载连接以及初始化

类的初始化顺序

Objective c类的初始化

类的初始化列表的必要性