Java 类的 Linking 和 Initializing 简单笔记

简介: Java 类的 Linking 和 Initializing 简单笔记

       Java 类的生命周期分为 5 个阶段,分别是 Loading(加载)、Linking(连接)、Initializing(初始化)、Using(使用) 和 Unloading(卸载)。其中 Linking 阶段又分为 Verification(验证)、Preparation(准备) 和 Resolution(解析) 三个部分。

       大致情况如下图所示。

11111.png

       一般所说的类加载指的是 Loading、Linking 和 Initializing 这几个阶段。其中,Loading 主要讨论关于 双亲委派、懒加载、自定义类加载器等相关的知识。在 Linking 的 Preparation 阶段 和 Initializing 可以了解类静态成员变量的初始化。在学习 Java 的相关基础知识时,了解内部的工作机制,要比单纯记忆相关语法规则可能更容易理解。这里,通过一个简单的代码实例来了解一下在 Preparation 阶段和 Initializing 阶段的对类中静态变量的赋初始值与初始化的过程。


一、一段没有意义的代码

       下面的代码是一段没有意义的代码,项目中也不会有如此的写法,但是通过下面的代码能够很好的解释静态变量在每个阶段时的值。

publicclassLinking {
publicstaticvoidmain(String[] args) {
System.out.println(Test.count);
    }
}
classTest {
publicstaticintcount=2;
publicstaticTesttest=newTest();
privateTest() {
count++;
    }
}

       上面的代码,主要用来输出 Test 类中的 count 静态变量的值。从 Test 类中可以看到,定义了静态的 int 型变量 count 和 静态的 Test 类对象。在 main 中输出时,Test.count 的值是多少。这里通过编译并运行代码来进行查看结果。

22222.png

       在 IDEA 中的输出结果是 3。对于这个结果,能够了解在整个类加载时 Preparation 阶段和 Initializing 阶段 时的所作所为,即可了解该值为何如此输出。


二、Linking 阶段和 Initializing 阶段的所作所为

       在类加载的 Linking 阶段中,主要完成了三个步骤,分别是 Verification、Preparation 和 Resolution。其中,Verification 是用来验证 class 文件是否符合 JVM 的规范,比如文件格式校验、元数据校验、字节码校验 和 符号引用校验。在类验证通过后是 Preparation,该步骤主要为类中定义的静态成员变量分配内存,并为静态成员变量赋默认值。Resolution 用来完成符号引用到直接引用的解析,可以理解为将 class 文件的常量池的各种符号引用解析为内存地址的指针引用。

       Initializing 阶段用来完成类的初始化代码,其中包含静态成员变量的初始化。


三、解释代码

       有了上面两个阶段大体的工作内容,再来看一下代码。在代码中,定义了一个 Test 类,类中定义了两个静态的成员变量,分别是 int 型和 Test 类。在 Preparation 阶段,会为这两个静态成员变量分配空间,赋默认值。那么此时为 count 静态变量赋默认值,int 类型的默认值为 0,那么 count 的值为 0;类对象的默认值为 null,那么 test 的值为 null。在 Initializing 阶段,count 的值根据代码被初始化为 2,test 在经过构造方法的执行后,count 的值进行了自增 1 的操作,由 2 变为了 3。因此,在 main 方法中,输出 Test.count 时,它的值为 3。


四、修改代码

       修改上面的代码,调整两个静态成员变量定义的顺序,再来观察它的输出结果,代码如下:

classTest {
publicstaticTesttest=newTest();
publicstaticintcount=2;
privateTest() {
count++;
    }
}

       接着按照上面的方式进行分析。首先,在 Preparation 阶段,test 的默认值为 null,count 的默认值为 0。接着,在 Initializing 阶段,调用 Test 的构造方法,此时 count 经过自增 1 变为了 1,再来完成 count = 2 的初始化。最后在 main 方法中输出 Test.count 时,它的值为 2。输出结果如下:

33333.png

五、总结

       上面的内容中,介绍了 Java 类在加载时的部分内容,也从例子代码对其机制有了简单的了解。很多时候,语法规则细节之类的并不是能特别好的记住,有些知识也并不是完全靠记就好使的,更多的是了解技术背后的一些原理,这样对知识的掌握才能更加深刻。

相关文章
|
3天前
|
存储 Java
Java Scanner类详解与应用
Java Scanner类详解与应用
|
1天前
|
Java 安全 索引
滚雪球学Java(48):面向对象编程中的StringBuffer类详解
【6月更文挑战第2天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
23 5
滚雪球学Java(48):面向对象编程中的StringBuffer类详解
|
2天前
|
搜索推荐 算法 Java
JAVA中的交换类排序算法详解
JAVA中的交换类排序算法详解
8 1
|
2天前
|
存储 Java 测试技术
滚雪球学Java(47):String类教程:如何在Java中使用字符串操作
【6月更文挑战第1天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
14 2
滚雪球学Java(47):String类教程:如何在Java中使用字符串操作
|
3天前
|
JavaScript Java 测试技术
Java项目基于ssm+vue.js的网络类课程思政学习系统附带文章和源代码设计说明文档ppt
Java项目基于ssm+vue.js的网络类课程思政学习系统附带文章和源代码设计说明文档ppt
8 0
|
3天前
|
存储 Java 索引
Java笔记(3)
该文介绍了数据结构的基础知识,包括集合类型和遍历方式。集合分为ArrayList(有序、可重复、有索引)和Set(无序、不重复、无索引)。遍历集合可使用Iterator、增强for循环和Lambda表达式。HashMap是Map接口的实现,用于存储键值对,提供添加、删除、查找等操作。LinkedHashMap保持插入顺序。文章还提及了二叉树的概念,如平衡二叉树和红黑树,并列举了一些常用的Java开发快捷键,以及如何添加依赖。
12 2
|
3天前
|
安全 前端开发 Java
Java语言中的类装载机制详解
Java语言中的类装载机制详解
|
3天前
|
Java API Apache
Java语言中常用工具类的技术性分析
Java语言中常用工具类的技术性分析
|
3天前
|
存储 Java
Java语言中的类与对象:深入理解与实践
Java语言中的类与对象:深入理解与实践
|
3天前
|
存储 Java
Java类与对象的技术性文章
Java类与对象的技术性文章
20 0