类装载流程
Loading
- 通过全限定类名产生对应二进制流
- 分析转化为方法区(永久代jdk1.7 元空间jdk1.8)的特定的数据结构
- 创建对应class实例
Linking
- verify:验证字节码的正确性
- prepare:准备阶段,初始化所有的类变量(static修饰),值为变量初始值。final修饰的除外。(final修饰的为常量,已经在类编译为字节码的时候已经确定)
- resolve:将常量池中的符号引用转化为直接引用
Initialization
运行Clinit方法:整合了所有类变量的赋值动作,与静态代码块的语句。
类加载器
JVM的规范将类分为两种:
- 引导类加载器BootStrapClassLoader
- 自定义类加载器:凡是继承或者间接于ClassLoader的加载器
JVM自带的加载器有:
- 引导类加载器BootStrapClassLoader
- 拓展类加载器ExtClassLoader
- 系统类加载器 AppClassLoader
如何去实现自定义类加载器?
- 在JDK1.2之前,需要在继承ClassLoader之后去重写loadClass()方法
- 在JDK1.2之后,不推荐去覆盖loadClass(),而是去重写findClass()
- 在编写自定义类加载器时,如果没有复杂的业务逻辑,可以直接继承URLClassLoader()这样就可以避免编写findClass()方法与处理字节码流。
为什么要自定义类加载器?
- 隔离加载类
使用中间件时遇到类的冲突 - 拓展新增加载源
例如加载数据库中的类 - 防止源码泄漏
解密已经加密过的字节码
双亲委派机制
流程
- 当程序需要去加载一个新的类时,类加载器不会马上去加载,而是委托给父加载器加载
- 若父加载器仍然有双亲,则继续向上委托
- 当父加载器存在该类则加载,不存在才由子类进行加载
目的(安全)
- 防止核心API被篡改
- 避免类重复加载
引申:判断两个Class对象是否是同一个类的依据?
- 全限定类名必须一致
- 类加载器必须一致
沙箱安全机制
java的安全模式的核心:沙箱安全机制(sandBox)将java代码限定在特定的虚拟JVM中运行,从而不会影响外部的环境。