一、需明白的几个概念
<init> 实例的初始化方法
就是我们说的构造器,构造器就包括 构造方法、{}包住的代码等。
<clinit> 类的初始化方法
1、<clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static{}语句)中的语句合并产生的,编译器收集的顺序是有语句在源文件中出现的顺序所决定的,静态语句块中只能访问到定义在静态语句块之前的变量,定义在它之后的变量,在前面的静态语句块中可以赋值,但不能访问。
2、<clinit>()方法与类的构造函数(实例化<init>()方法)不同,他不需要显示地调用父类构造器,虚拟机会保证在子类的<clinit>()方法执行之前,父类的<clinit>()方法执行完毕。虚拟机第一个被执行的<clinit>()方法肯定是java.lang.Object()。
3、由于父类的<clinit>()方法先执行,所以父类定义的静态语句块要优先于子类的变量赋值操作。
4、如果一个类中没有静态语句块,也没有对变量的赋值操作,编译器不必为类生成<clinit>()方法。
5、接口不能使用静态语句块,但仍有变量初始化的赋值操作,会生成<clinit>()方法。接口的<clinit>()方法不需要先执行父类接口的<clinit>()方法,当父类接口中定义的变量被使用时,父接口才会被初始化。接口的实现类在初始化时不会执行接口的<clinit>()方法。
6、一个类的<clinit>()方法在多线程环境中执行时,只会有一个线程去执行<clinit>()方法,其余线程都需要阻塞等待,直到活动线程执行<clinit>()方法完毕。
init is the (or one of the) constructor(s) for the instance, and non-static field initialization.
clinit are the static initialization blocks for the class, and static field initialization.
<init>是instance实例构造器,对非静态变量解析初始化。而<clinit>是class类构造器对静态变量,静态代码块进行初始化
<init>与<clinit>加载顺序
当一个类初始化的时候,先调用<cinit>方法 ,如果在<cinit>方法中遇到<init>方法。则先调用完<init>方法。然后在继续执行<cinit>

本文详细介绍了JVM中的类加载初始化过程,重点讨论了<init>(实例初始化)和<clinit>(类初始化)方法。<init>是实例构造器,负责非静态字段的初始化,而<clinit>则是类构造器,用于静态字段和静态代码块的初始化。在多线程环境下,<clinit>方法的执行具有同步性,确保线程安全。文章通过实例展示了<init>与<clinit>的加载顺序,先执行<clinit>,在其中遇到<init>时,会先完成<init>的执行。
最低0.47元/天 解锁文章
3188

被折叠的 条评论
为什么被折叠?



