• 类加载器子系统负责从文件系统 或网络中加载.class文件
• ClassLoader只负责class文件的加载,主语是否允许由ExecutionEngine决定
• 加载的类的信息存放于一块称为方法区的内存空间。
类的加载过程:
- 加载阶段
- 通过一个类的全限定名获取定义此类的二进制字节流
- 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
- 在内存中生成一个代表这个类的java.lang.Class对象,作为该方法区这个类的各种数据的访问入口
- 链接阶段
- 验证:目标在于确保Class文件的字节流中包含的信息符合当前虚拟机的要求
- 准备:为类变量分配内存并赋初值,这里不包括final修饰的static,因为final在编译时就分配。准备阶段会显式初始化,不会为实例变量分配初始化
- 解析
- 将常量池内的符合引用转换为直接引用
- 解析往往伴随着JVM在执行完初始化之后再执行
- 符合引用就是一组符号来描述所引用的目标,直接引用就是直接指向目标的指针
- 解析动作主要是针对类的接口,字段,类方法,方法类型等
- 初始化阶段
- 初始化阶段就是执行类的构造器(),在执行类构造器()时保证父类的()已经执行完毕
- 在这个阶段先执行静态块代码并且为静态变量赋值为初始值。
Java程序主动使用类:
- 创建类的实例
- 访问某个类的接口的静态变量或对静态变量赋值
- 调用类的静态方法
- 反射
- 初始化一个类的子类
- Java虚拟机启动时被标明为启动类的类
- 动态语言(invoke)
双亲委派机制
原理:
- 如果一个类的加载器收到了加载请求。它并不会自己去加载,而是把这个请求委托给父类的加载器去执行
- 如果父类的加载器还有父类的加载器则一步一步向上委托。直到达到顶层的启动加载器
- 如果父类加载器能完成任务,就返回成功,否则子类加载器自己尝试去完成任务
优势:避免类的重复加载,保护程序安全避免核心API被随意篡改