类生命周期
![](https://i-blog.csdnimg.cn/blog_migrate/88ba4c2151e4e86bc7cf57a03e7259e0.png)
- 类加载过程
![](https://i-blog.csdnimg.cn/blog_migrate/ee8b39f47b6d3c5d6194e50432c0b0f1.png)
加载
![](https://i-blog.csdnimg.cn/blog_migrate/2ce2adfaa737a3d5d14be7065a9a0d86.png)
过程
![](https://i-blog.csdnimg.cn/blog_migrate/8ab690c1121c1dc6651221ac1dd70975.png)
获取定义类的二进制字节流
![](https://i-blog.csdnimg.cn/blog_migrate/ba91d603f42643958b5e6d83a51f9d19.png)
获取方式
![](https://i-blog.csdnimg.cn/blog_migrate/d61b39df95210f2bc3ba57bc2bdad86c.png)
zip包
网络
运算时生成
其他文件生成
数据库
将字节流转化为方法区的运行时数据结构
在内存中生成一个代表该类的java.lang.Class对象
连接
![](https://i-blog.csdnimg.cn/blog_migrate/e4723ecad90aa04633f4cf465ee0ebcd.png)
验证
![](https://i-blog.csdnimg.cn/blog_migrate/cd13466dc954020c82350537c37511f3.png)
文件格式验证
元数据验证
字节码验证
符号引用验证
准备
![](https://i-blog.csdnimg.cn/blog_migrate/3aee5a0513bac5ca9662742670bf5eed.png)
为类变量分配内存并赋初0值
解析
![](https://i-blog.csdnimg.cn/blog_migrate/7855f3bf5e4290318a0f65d17053849d.png)
将符号引用替换为直接引用
![](https://i-blog.csdnimg.cn/blog_migrate/6a70a4121ef32829357ba1090b137de1.png)
类或接口解析
![](https://i-blog.csdnimg.cn/blog_migrate/74900f46a9ef2d6731d081e677fe4f80.png)
不是数组类型传递全限定名用类加载器加载
时数组类型且元素为对象,按上一步加载元素类型
符号引用验证
字段解析
![](https://i-blog.csdnimg.cn/blog_migrate/1b9efb400f493159b361d76d0fdadb42.png)
class_index符号引用解析
![](https://i-blog.csdnimg.cn/blog_migrate/a5d0a392f31ab40f7db473c2c86fb7b0.png)
所在类包含简单名称和字段描述符匹配的字段,返回该字段直接引用
若有接口,从下往上搜索接口,若接口中包含匹配字段则返回匹配的直接引用
若不是java.lang.Object,从下往上搜索父类,若有匹配字段则返回字节引用
查找失败
类方法解析
![](https://i-blog.csdnimg.cn/blog_migrate/e10113f253ded3dae468fddfb870f005.png)
class_index符号引用解析
![](https://i-blog.csdnimg.cn/blog_migrate/0988b90a79f4418dc6a9c5fc3d953a4a.png)
解析结果是接口抛异常
在类中查找是否有匹配方法,有则返回
在父类中查找是否有匹配方法,有则返回
在接口列表及它们父接口中查找是否有匹配方法,有则返回
失败
接口方法解析
![](https://i-blog.csdnimg.cn/blog_migrate/4fd0542f29c3ecac5a981d460bfc86ba.png)
class_index符号引用解析
![](https://i-blog.csdnimg.cn/blog_migrate/bb82aae09571c9b34a66ac7f2bed564c.png)
解析结果是类,抛异常
在本接口中查找是否有匹配方法,有则返回
在父接口中查找是否有匹配方法,有则返回
失败
初始化
![](https://i-blog.csdnimg.cn/blog_migrate/8f7a91f8684b519a71e975edefed872d.png)
时机
![](https://i-blog.csdnimg.cn/blog_migrate/713e9ebfee1eeb183d2cc4cfc61291be.png)
遇到new,getstatic,putstatic或invokestatic指令
使用java.lang.reflect包的方法对类反射调用
子类要先触发父类的初始化
用户指定要执行的主类
使用动态语言支持时的一些情况
过程
![](https://i-blog.csdnimg.cn/blog_migrate/93e7689791bb4588d8a4880be3ee85a2.png)
执行类构造器的<clinit>()方法
![](https://i-blog.csdnimg.cn/blog_migrate/d96f22e21637f162097a4121f25ed0de.png)
<clinit>()方法
![](https://i-blog.csdnimg.cn/blog_migrate/0f7584e112679e8907af3dec7b1da1c6.png)
产生
![](https://i-blog.csdnimg.cn/blog_migrate/a12a1849c6906fefa4e6bb4f5feb8e1a.png)
类变量的赋值动作
静态语句块
与构造函数区别
![](https://i-blog.csdnimg.cn/blog_migrate/476d47adea72a81c05bc4523c3a81807.png)
不需要显式调用父类构造器,虚拟机保证父类的<clinit>()方法在子类之前执行
第一个被执行<clinit>()方法的是java.lang.Object类
类可能不被生成<clinit>()方法
接口中也会生成<clinit>()方法,但不需要先执行父接口的<clinit>()方法
<clinit>()方法会被自动同步执行
- 其他
![](https://i-blog.csdnimg.cn/blog_migrate/bf6f7e161c06e90941db7cc6b14dccaa.png)
使用
卸载