Java类加载的过程
JVM把描述类的数据从Class文件加载到内存,并对数据进行校验,解析和初始化,最终变成可以被JVM直接使用的Java类型
(因为可以动态产生,这里的Class文件并不是具体存在磁盘中的文件,而是二进制数据流)
- 加载(Loading)
- 链接(Linking)
- 验证 --确保字节码文件的格式正确,运行时不会危害虚拟机的安全
- 准备 --主要为类的静态资源变量分配内存,并将其初始化为默认值
– 如果类静态变量的字段属性中存在ConstantVallue属性,则直接执行赋值语句
- 类静态变量为基本数据类型被final修饰
- 类静态变量为String类型被final修饰,并且以自面量的形式赋值
- 解析 --将类,接口,字段和方法的符号引用转为直接引用 - 初始化(Initialization)–执行类静态成员变量赋值语句和静态代码块中的语句
- 使用(Using)
- 卸载(Unloading)
类加载的过程中双亲委派机制
原理:
- Java运行必须经过编译和类加载
- 编译就是将java文件变成字节码文件,类加载过程就是将字节码文件加载到JVM内存里面,装载完成会得到一个class对象,可以使用new关键字来实例化这个对象
- JVM在运行的时候会产生三个类加载器,组成层级关系,每一个类加载器分别加载不同作用范围的Jar包
- 类加载器分类
- 启动类加载器(Bootstrap ClassLoader) ==》负责Java核心类库的加载(%JAVA_HOME%\lib下的jar包)
- 扩展类加载器(Extension ClassLoader) ==》负责%JAVA_HOME%\lib\ext下的jar包和class文件
- 应用类加载器(Application ClassLoader)==》当前应用里面classpath下面的所有jar包和类文件
- 自定义类加载器(User ClassLoader) ==》满足特殊的场景需求
好处:
- 提高安全性,所有的类都会给到父类加载器,每个类加载器的本身有自己的作用范围,避免对核心类库的破坏
- 避免重复加载导致程序混乱,父类加载过的文件子类就不必再去加载