在我们Java中类的加载和连接过程都是在程序运行期间完成的。
一般我们的类从它被加载到虚拟机内存,和到被卸载出内存为止:它的生命周期可以细分为:加载 - 验证 - 准备 - 解析 - 初始化 - 使用 - 卸载。
我们统一把验证,准备,和解析阶段统称为连接阶段。一般我们说的类加载完成包括三个阶段,加载 - 连接 - 初始化。下面我们就来了解了解这三个阶段做了哪些事。
1.加载阶段
加载阶段是我们平时所说的类加载完成的第一个阶段,这个阶段主要做了以下三件事:
-
获取此类的二进制字节流。
-
将字节流所代表的存储结构转化为方法区的运行时结构。
-
在Java堆上生成一个代表这个类的Class对象。
加载阶段是开发期可控性最强的阶段,我们可以使用系统的类加载器去完成,也可以使用自定义的加载器去完成。
2.连接阶段
在这一阶段我们我们主要做了下面几件事:
1.验证我们的Class文件中的字节流是否符合我们虚拟机的要求,并且不会危害虚拟机的自身安全。
2.为我们的类变量分配内存并设置类变量的初始值。(类变量是我们static修饰的变量,不要和不是static修饰的成员属性(实例变量)混淆。)
还要注意一点就是设置类变量的初始值,不等同于我们的赋值操作。
比如 static int a = 2;这个阶段完成以后,我们的a的初始值为0,而非2(被final修饰的常量除外)。这个我们后面说到类的初始化的时候再讲。
3.将常量池的符号引用替换为直接引用(符号引用,引用的目标并不一定以及加载到内存,直接用引用,目标一定已经被加载到内存)。
3.初始化阶段
在初始化我们做的主要事情就是初始化我们的类变量和我们在程序中编写的初始化操作。上面我们在连接阶段提到的a被初始化为零值,在我们的初始化阶段我们为我们的类变量进行赋值操作。
虚拟机严格规定了有且只有四种情况必须立即对类进行初始化。
1.遇到new ,getstatic,putstatic,invokestatic这四条字节码指令时。
new就是我们所熟悉的在实例化对象的时候,getstatic,putstatic,invokestatic是什么呢?就是我们在获取和设置一个static变量(final修饰的类变量除外,final修饰的类变量,在编译期已经把结果放入常量池。)时,还有我们在调用我们类的静态方法的时候。如果类没有被初始化,必须立即对类进行初始化。
2.在我们使用反射对类进行发射调用的时候。
3.当我们初始化一个类的时候,发现其父类没有初始化,必须先对其父类进行初始化。
4.当虚拟机启动时,我们的主类会被初始化(包含main()方法的那个类)。
下面我们通过我们的代码来验证以下,类的初始化过程。
除了上面的四种情况,其他任何一种情况,都不会触发类的初始化操作。
下面我们来举个例子验证以下,我们上面所说的几种情况:
我们先定义两个类:一个Person类和Person类的子类Person类。
public class Person {
public static int a = 10;
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
最后
文章所有资料全部已经打包整理好,免费分享给有需要的人,另外小编手头上整理了大量Android架构师全套学习资料,Android核心高级技术PDF文档+全套高级学习资料+视频+2021 BAT 大厂面试真题解析,都是免费分享给大家的,全部都已整理在GitHub上,有需要的朋友可以点击前往领取更多。
资料展示:
f-1710739197851)]
[外链图片转存中…(img-0QspRA7Z-1710739197851)]
[外链图片转存中…(img-bzkBzcRl-1710739197852)]