当前位置:网站首页>JVM的类加载过程

JVM的类加载过程

2022-06-21 19:23:00 斯沃福德

1. 加载

java源代码编译为字节码后,然后通过类加载器加载字节码到方法区中,并根据Class 文件描述在堆中创建 java.lang.Class 对象

2. 链接

2.1. 验证:

验证字节码是否符合虚拟机规范 ,不合法的将会报错ClassFormatError

2.2. 准备:

2.为static静态变量分配空间,设置默认值
JDK1.6中静态变量在方法区,现在的JDK1.8 中静态变量在堆中
static静态变量分配空间和赋值是两个步骤,分配空间在准备阶段完成,赋值在初始化阶段类的构造中完成
· 如果是static final 基本类型特殊,值在编译阶段就确定了,赋值在准备中完成
· 如果是static final 引用类型,那么赋值也会在初始化阶段完成

2.3. 解析:

指的是将常量池中的符号引用解析为直接引用,
符号引用仅仅是符号,并不知道类、方法在内存的什么位置,但是经过了解析之后,就知道了类、方法在内存的确切位置

loadClasss()方法只加载,但不会导致类的解析和初始化
new() 会做解析和初始化

3. 初始化

初始化就是去执行类的构造方法,虚拟机会保证这个类的构造方法的线程安全
发生时机:
初始化是懒惰的
main方法时间首先会被初始化
首次访问这个类的静态变量(不是final的),静态方法时
子类的初始化:如果父类还没初始化会先初始化父类
子类访问父类的静态变量,只会触发父类的初始化,子类并不会被初始化
Class.forName会导致类的初始化 (newInstacnce()方法会执行无参构造)
new()对象会导致初始化
不会导致初始化:
访问static final静态常量(基本类型、字符串)不会触发初始化,其都在链接的准备阶段就完成了变量的赋值
使用ClassLoader默认的loadClass方法加载类时不会触发该类的初始化
创建类的数组不会导致初始化
在子类引用父类的静态字段时,不会触发子类的初始化,只会触发父类的初始化。
loadClasss()方法只加载,但不会导致类的解析和初始化

原网站

版权声明
本文为[斯沃福德]所创,转载请带上原文链接,感谢
https://blog.csdn.net/Swofford/article/details/125395277