1、类加载过程
一共分为5个阶段:加载、验证、准备、解析、初始化,逐个说明。
加载阶段
- 通过类的全限定类名获取这个类的二进制字节流
- 将类字节流的静态存储结构转化为方法区的运行时数据结构
- 在内存当中生成这个类的java.lang.Class对象,并作为在方法区该类数据的访问入口
验证阶段
验证类的字节流是否符合JVM虚拟机的规范。
主要检查的是:
- 文件格式验证:判断当前字节流是否符合Class文件格式要求
- 元数据验证:判断数据类型是否符合Java语言规范
- 字节码验证:判断方法是否符合Java语言规范
- 符号引用验证:判断方法是否符合Java语言规范
准备阶段
为类中静态变量赋初始值,类变量分配空间是在准备阶段完成,赋值是在初始化中执行
final修饰的静态变量如果是基本类型,在准备阶段就赋值了,值就被定下来了
final修饰的静态变量如果是引用类型,赋值也是在初始化阶段完成
解析阶段
将常量池中的符号引用变为直接引用
初始化阶段
初始化类的最后一步,也就是调用方法
2、双亲委派机制
类加载器分类
启动类加载器:加载JVM自身需要的类,它会把JAVA_HOME/lib下的核心类库加载进来
扩展类加载器:这个类加载器加载的是以前SUN公司JAVA_HOME/lib/ext的目录
应用程序类加载器:加载getClassLoader()中加载的类,也就是系统类的加载器
自定义类加载器:就是自定义的类
双亲委派
如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器,如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式,即每个儿子都很懒,每次有活就丢给父亲去干,直到父亲说这件事我也干不了时,儿子自己想办法去完成
为什么要采用双亲委派机制
是为了避免重复加载类,如果父类加载器加载过该类,子类加载器就不再加载了。