04_类加载
类加载
什么时候需要进行类加载
- new、putstatic、getstatic、invokestatic字节码指令时,如果尚未初始化,则需要先触发初始化
- 对类进行反射调用时
- 初始化一个类时,如果父类尚未初始化
- 虚拟机启动时,用于需要指定一个包含main()方法的主类,虚拟机会先初始化这个主类
加载类的过程
- 加载:查找并加载类的class文件,该class文件可以来自本地磁盘和网络等,通过IO的手段加载诚2进制的流
- 验证:确保类型的正确性,比如class文件的格式是否正确、语义是否符合语法规定、字节码是否可以被JVM安全正确的执行等
- 准备:为类的静态变量分配内存,并赋初始值。比如int类型的赋值为0,引用类型赋值为null
- 解析(最复杂):将符号引用转为直接引用
- 初始化:为标记为常量值得字段赋值的过程。只对static修饰的变量或语句进行初始化,如果初始化一个类的时候,其父类尚未初始化,则优先初始化其父类。
类加载器
将class文件加载进JVM的方法区,并在方法区中创建一个Java.lang.class对象作为外界访问这个类的接口
类加载器的分类
- 启动类加载器:加载类的路径为<JAVA_HOME>/jre/lib/
- 扩展类加载器:加载类的路径为<JAVA_HOME>/jre/libext/
- 应用程序加载器:最广泛的类加载器,负责加载用户classpath下的class文件,也叫系统加载器
- 自定义类加载器
双亲委派模型
如果一个类加载器收到加载类的请求,它首先将请求交给父类加载器加载,若父类加载器加载失败,当前类加载器才会自己加载类