类的初始化

1)类的初始化阶段是类加载过程的最后一个步骤。

​ 类加载过程即加载、 验证、 准备、 解析和初始化。

image-20201005100703128

2)直到初始化阶段, Java虚拟机才真正开始执行类中编写的Java程序代码, 将主导权移交给应用程序。

3)**根据程序员的要求去真正初始化类变量和其他资源。**和前面准备阶段不一样。

4)初始化阶段就是执行类构造器**< clinit >()方法**的过程。

< clinit >()方法介绍:

1)所有的类变量初始化语句(显示赋值)和类型的静态初始化器

​ 在static语句块中使用到静态变量时一定要将该静态变量的声明语句放在static语句块的前面, 否则会发生illegal forward references的编译错误

2)< clinit >()方法与类的构造函数(即在虚拟机视角中的实例构造器<init>()方法) 不同, 它不需要显
式地调用父类构造器, Java虚拟机会保证在子类的<clinit>()方法执行前, 父类的<clinit>()方法已经执行完毕。

3)由于父类的<clinit>()方法先执行, 也就意味着父类中定义的静态语句块要优先于子类的变量赋值
操作 。

为什么初始化子类需要先初始化父类:

​ 从理论上来说,既然你要初始化子类,子类会继承父类的一部分属性和方法,如果你不初始化父类,那么子类就没有意义。继承不了父类的属性和方法。

注意: 并非所有的类都会拥有一个<clinit>方法, 满足下列条件之一的类不会拥有<clinit>方法:
该类既没有声明任何类变量,也没有静态初始化语句;
该类声明了类变量,但没有明确使用类变量初始化语句或静态初始化语句初始化;
该类仅包含静态 final 变量的类变量初始化语句,并且类变量初始化语句是编译时常量表达式;

初始化顺序

重点是分清<clinit>方法和<init>方法。

1.类的初始化

前置知识:

1)一个类要创建实例,要先加载并先初始化这个类。

2)子类初始化要先初始化父类

3)类的初始化由<clinit>()方法实现。

类的初始化顺序:

1)初始化父类

2)初始化自己(执行类变量赋值语句和静态代码块)

2.对象初始化(构造方法)

前置知识:

1)创建一个类的对象之前,必须先进行类的初始化。

2)<init>()方法首行是super(),即父类的<init>()方法

所以,创建一个子类实例过程为:

1)初始化子类(先初始化父类)

2)执行子类<init>()方法(先执行父类<init>()方法

<init>()方法:由非静态实例变量显示复制代码和非静态代码块、对应的构造器代码组成,并顺序执行,只执行一次

综上,对象初始化顺序为:

执行父类的静态变量赋值语句和静态代码块—>执行子类的静态变量赋值语句和静态代码块–>执行父类的非静态代码块—>执行父类构造函数函数—>执行子类非静态代码块—>执行子类构造函数

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐