Java类加载过程
Posted 进阶的程序猿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java类加载过程相关的知识,希望对你有一定的参考价值。
一.类加载过程简介
类的加载一般分为三个比较大的阶段,分别是加载阶段、连接阶段和初始化阶段。
1.加载阶段
主要负责查找并且加载类的二进制数据文件,其实就是class文件
2.连接阶段
连接阶段所做的工作比较多,主要分为以下三个阶段:
(1)验证阶段
主要是保证确保类的正确性,譬如class文件的版本,class文件的魔术因子是否正确。
(2)准备阶段
为类的静态变量分配内存,并且为其初始化默认值。
(3)解析阶段
把类中的符号引用转换成直接引用。
- 初始化阶段
为类的静态变量赋予正确的初始值也就是代码编写阶段给定的值。
一.ClassLoader介绍
ClassLoader 的主要职责是负责加载各种class文件到JVM中,ClassLoader是一个抽象的class,给定一个class的二进制文件名,ClassLoader会尝试加载并且在JVM中生成构成这个类的各个数据结构,然后使其分布在JVM对应的内存区域中。
二.类的主动使用和被动使用
JVM虚拟机规范规定,每个类或者接口被Java程序首次主动使用时才会对其进行初始化,但是不排除JVM在运行期间提前预判并且初始化某个类。
JVM同时规范了以下6中主动使用类的场景,具体如下:
(1)通过new关键字会导致类的初始化,并且是最终的初始化。
(2)访问类的静态变量,包括读取和更新会导致类的初始化。
public class Simple {
static{
System.out.println("初始化");
}
public static int x = 10;
}
以上代码中直接访问变量x也会导致类的初始化。
(3)访问类的静态方法,会导致类的初始化。
public class Simple { static{ System.out.println("初始化"); } public static int x = 10; //静态方法 public static void test(){ } }
以上代码中直接调用test静态方法也会导致类的初始化。
(4)对某个类进行反射操作,会导致类的初始化。
(5)初始化子类会导致父类的初始化,通过子类使用父类的静态变量,只会导致父类的初始化,子类则不会被初始化。
(6)启动类,也就是执行main函数所在的类会导致该类的初始化。
除了以上的6种情况,其余的都称为被动使用,不会导致类的加载和初始化。
(1)构造某个类的数组时并不会导致该类的初始化。
Simple[] simples = new Simple[10]; System.out.println(simples.length);
(2)引用类的静态常量不会导致类的初始化。
public final static int MAX = 100;
以上是关于Java类加载过程的主要内容,如果未能解决你的问题,请参考以下文章
14.VisualVM使用详解15.VisualVM堆查看器使用的内存不足19.class文件--文件结构--魔数20.文件结构--常量池21.文件结构访问标志(2个字节)22.类加载机制概(代码片段