Java 的两种类内变量初始化方式:
- 成员变量:在实例构造器
<init>
方法中进行,比如 int x = 1 - 类变量:在类构造器
<cinit>
方法中或者使用 class ConstantValue 属性,static int x = 1:
这里再多说一句,对于 static 变量的初始化,目前 Sun Javac 编译器的选择是:如果同时使用 final 和 static 来修饰一个变量,并且这个变量的数据类型是基本类型或者 java.lang.String 的话,就生成 ConstantValue 属性来进行初始化,如果这个变量没有被 final 修饰,或者并非基本类型及字符串,则将会选择在 方法中进行初始化。
注意,接口中的属性都是static final类型的常量,因此在准备阶段就已经初始化
1.init 方法
Java 在编译之后会在字节码文件中生成<init>
方法,称之为实例构造器,作用是初始化所有成员变量。
该实例构造器是由编译器自动生成,详细点说就是,将类中所有成员变量的赋值动作和语句块({}),全部收集到<init>
方法一起执行。收集的一般顺序为:
- 父类变量初始化
- 父类语句块
- 父类构造函数
- 子类变量初始化
- 子类语句块
- 子类构造函数
<init>
方法的执行时机是代码中 new 一个对象,比如 new A()。
2. cinit 方法
Java 在编译之后会在字节码文件中生成<cinit>
方法,称之为类构造器,作用是初始化所有类变量。
类构造器同实例构造器一样,都是有方法是由编译器自动生成,收集类的是所有类变量的赋值动作,和静态语句块(static{}块)中的语句。收集的一般顺序为:
- 父类静态变量初始化
- 父类静态语句块
- 子类静态变量初始化
- 子类静态语句块
<cinit>
方法的执行时机是 JVM 将 class 字节码文加载进来,初始化静态变量时。
两点注意:
- 虚拟机中第一个被执行的
<cinit>
方法的类肯定是 java.lang.Object,因为它是说有类的父类(基类) - 接口中不能使用静态语句块,但仍然有变量初始化的赋值操作,因此接口与类一样都会生成
<cinit>
方法。 但接口与类不同的是,执行接口的<cinit>
方法不需要先执行父接口的<cinit>
方法。 只有当父接口中定义的变量使用时,父接口才会初始化。 另外,接口的实现类在初始化时也一样不会执行接口的<cinit>
方法。
3.对象初始化流程
<cinit>
方法是在类加载过程中执行的,而<init>
是在对象实例化执行的,所以<cinit>
一定比<init>
先执行。所以整个顺序就是:
- 父类静态变量初始化
- 父类静态语句块
- 子类静态变量初始化
- 子类静态语句块
- 父类变量初始化
- 父类语句块
- 父类构造函数
- 子类变量初始化
- 子类语句块
- 子类构造函数
代码示例
// 父类
public class Parent {
// 父类静态变量,及初始值
static int a = 1;
// 父类成员变量,及初始值
int b = 1;
// 父类静态代码块
static {
System.out.println("parent static block(a):" + (++a));
}
// 父类普通代码块
{
System.out.println("parent block(b):" + (++b));
}
public Parent() {
System.out.println("parent construction");
}
}
// 子类
public class Child extends Parent {
// 还是 a、b
static int a = 1;
int b = 1;
static {
System.out.println("child static block(a):" + (++a));
}
{
System.out.println("child block(b):" + (++b));
}
public Child() {
System.out.println("child construction");
}
// 入口
public static void main(String[] args) {
new Child();
}
}
最终结果
parent static block(a):2
child static block(a):2 // 虽然在父类已经成 2 了,但是在子类又初始化了
parent block(b):2 // 父类代码块
parent construction // 父类构造函数
child block(b):2
child construction
参考链接:
- https://blog.csdn.net/u013309870/article/details/72975536
- https://blog.csdn.net/sujz12345/article/details/52590095?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control