类加载详述以及双亲委派模型
一、简介类加载过程
在上一文中,已经简单的讲解过类加载的步骤,此处稍做复习一下,不经意一看,已经是三月份的文章了...(文章链接)
类加载机制大方向分为三个步骤:
1、加载:用于查找和导入Class文件。
2、链接(链接又分为如下三个步骤):
- 校验:用于校验二进制文件的合法性;
- 准备:给类的静态变量分配内存,被赋上默认值;
- 解析:将符号引用转化为直接引用;
(个人理解:符号引用用于描述导入的类,接口,方法,以及字段,由于在JVM还未启动时,是无法定位到导入类的地址的,这个阶段就是将符号引用转化为内存中的直接引用)
3、初始化:此时才开始执行Java代码,给静态变量赋上初始化的值,并执行静态代码块。
二、类加载的特性
首先,何时进行类加载?
- 当实例化一个对象时,会对类进行加载;
- 当加载类的子类时,会对类加载;
- 当调用类的静态方法以及静态成员变量时;
- 使用反射Class.forName加载类;
- main方法的启动类;
再,类加载中,静态代码的执行顺序:
只需要记得,先变量,后方法,先父类,后子类,先静态代码块,再成员变量。
三、双亲委派模型
类加载是由类加载器完成的。
类加载器又分为四种:
- BootStrap ClassLoader,启动类加载器:用于加载jre/lib目录底下的class文件;
- Extension ClassLoader,扩展类加载器:用于加载jre/ext/lib底下的class文件;
- Application ClassLoader,应用类加载器:用于加载应用的类目录底下的class文件;
- 自定义类加载器:手动继承ClassLoader类实现;
再看这么一张图片:
所谓双亲委派模型,指的就是,当类加载器加载类文件时,会首先地委派父类加载器去加载类,如果所有的父类都无能为力的时候,才会让子类加载器去加载类。
这么做的优点:设想一种情况,如果我们重写了一个Object类,并放入classpath底下,此时如果没有双亲委派模型,就会出现多个不同的Object类。