Article Outline
java字节码与类加载
字节码加载过程
- 加载:查找class文件
- 验证: 验证格式、依赖
- 准备:静态字段,方法表
- 解析:将符号解析为应用 例如:jvm中String ---》3 ,则将代码中的String 替换为 3
- 初始化:初始化构造器,静态变量赋值,静态代码块
- 使用
- 卸载
类的加载时机
- 当虚拟机启动时,初始化用户指定的主类,即main方法所在的类
- 当用于新建目标类实例的new指令时,初始化new指令的目标类,就是new一个类对象的时候要加载。
- 当遇到调用静态方法的指令时,初始化该静态方法所在的类
- 当遇到访问静态字段的指令时,初始化该静态字段所在的类
- 子类初始化的时候会触发父类的初始化
- 如果一个接口定义了default方法,那么直接实现或者间接实现该接口的类的初始化,会触发该接口的初始化
- 使用反射API对某个类进行反射调用时,初始化这个类。
- 初次调用methodhandle实例时,初始化该methodhandle指向的方法所在的类。
三种类加载器
- 启动类加载器: 用于加载核心类,如jt.jar
- 扩展类加载器: 用于加载扩展类,如额外的jar包等
- 应用类加载器:用于加载如自己编写的程序
加载器特点
负责依赖:加载该类,还要加载该类的依赖类
缓存加载:只会加载一次,之后jvm会缓存加载的类
双亲委托
应用类加载器要加载某个类的时候,会先看他的父类加载器有没有加载该类(扩展类加载器),再由扩展类加载器查询启动类加载器是否加载了该类,如有加载则返回,如没有加载,则尝试加载,若无法加载到对应的类,交给子类处理。