类的声明周期
1· 加载
2. 验证
3. 准备
4. 解析
5. 初始化
6. 使用
7. 卸载
动态绑定/晚期绑定
1. 解析的时机是不确定的,它可以在初始化之后
加载的时机
1. 通过全限定的名称来获取定义此类的二进制流
验证
1. 确保class文件的字节流包含的信息符合当前虚拟机的要求
文件格式验证
1. 魔术 cafebabe
2. 主次版本号
3. 常量池是否有不支持的的常量类型
元数据验证
1. 所有类的爸爸都是object
字节码验证
1. 操作数栈的数据类型和指令代码的指令都能配合工作,比如在操作数栈上方int类型数据,使用时也按照int类型加载到本地变量表中
符号引用验证
1. 符号引用:对类自身外各类信息进行匹配校验
2. 比如类中是否存在符合方法的字段描述
验证
1. 对虚拟机很重要但是却非必要
2. 可以通过参数关闭
解析
1. jvm将常量池中的符号引用变成直接引用
2. 直接引用的对象都是存在内存中的,比如存在手机通信录的女友手机号,是符号引用,面对面吃饭就是直接引用
3. 常见的解析一场,类找不到,方法找不到
初始化
1. new getstatic 如果类没有初始化,就直接初始化
2. Java中立刻初始化的场景
1. new
2. 读取类的静态字段(final 或者 编译期间就放入常量池的静态字段除外)
3. 调用类的静态方法
4. 反射
5. 子类调用父类方法
jdk的三层类加载器
1. bootstrap classloader 加载核心类库,任何类加载都得问问他
2. extention classloader 扩展类加载器 java.extdirs
3. application classloader Java的默认加载类 加载classpath 下的jar .class文件
4. custom classloader 支持一些个性拓展功能
类加载器的问题
1. 类加载器和这个类本身确定了其在jvm中的唯一性
双亲委派模型
1. 除顶层启动类加载器之外,任何类加载器都应该有自己的父类,采用组合的方式复用父加载器代码
2. 好处就是每一次类加载都会向上询问,就可以边类似object 被重写
打破双亲委派模型
1. 自定义类加载器 tomcat 通过war 包进行应用发布,就违背了双亲委派
2.
3.
4. ![](https://img2020.cnblogs.com/blog/1279827/202008/1279827-20200803224919075-1764272708.png)
5. 隔离
spi
1. Java 中有一个 SPI 机制,全称是 Service Provider Interface,是 Java 提供的一套用来被第三方实现或者扩展的 API,它可以用来启用框架扩展和替换组件。
2. 比如jdbc 删掉classforname 也能正确加载
3. 这种方法也打破了双亲委派。凡是过问父亲,父亲不行了,就会把当前的类加载器变成线程的上下文类加载器,应用程序的类加载器,加载第三方驱动
osgi
1. OSGi 是服务平台的规范