类加载过程由加载,链接,初始化构成
加载阶段需要完成以下三个过程:
Bootstrap-ClassLoader基于C/C++实现,负责加载Java的核心类库JAVA_HOME\jre\lib\rt.jar,该加载器不继承自ClassLoader抽象类,并且只加载包名为java、javax、sun等开头类,一次保证对核心源码的保护
Extension-ClassLoader,基于Java语言,由sun.misc.Launcher$ExtClassLoader实现,派生于ClassLoader抽象类,从java.ext.dirs系统变量指定的路径中的加载类库,或者JDK安装目录jre\lib\ext目录下加载
Application-ClassLoader,基于Java语言,由sun.misc.Launcher$ExtClassLoader实现,它负责加载环境变量ClassPath指定的类库,如果在应用程序中没有自定义类加载器,一般情况下作为程序中默认的类加载器
主要作用
Java虚拟机对class文件采用的是按需加载方式,即当需要使用该类时才会将它的class文件加载到内存生成class对象,而且在加载某个类class文件时,Java虚拟机采取的是双亲委派模式,即将请求交由父类处理,它是一种任务委派模式
假设自定义一个类名为String且所在包为java.lang,在使用引导类加载器加载时会先加载JDK(rt.jar包下的java/lang/String.class)中的String类,因为这个类本来是属于jdk的,后面再次出现String类就会报错,以此保证核心源代码不被恶意篡改,这就是沙箱安全机制。
执行流程依次为验证->准备->解析
其目的在于确保Class文件的字节流中包含的信息符合当前虚拟机的要求,保证加载类的正确性,不会危害虚拟机自身的安全
验证内容:
为类的静态变量分配内存,并初始化为默认值,仅包括类变量(static修饰,不包括final-static修饰),这里也不会为实例变量分配初始化,实例变量会随着对象一块分配到Java堆内存中
比如:某类中定义一个静态变量:private static int i = 10;此时在准备阶段i = 0,在后续的初始化阶段才会被赋值为10
将常量池中的符号引用转换为直接引用的过程,直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。解析主要针对类或接口、字段、类方法、接口方法、方法类型等,解析的动作实际是会随着JVM在执行完初始化之后再执行的。