类加载机制
一、类的生命周期(java文件->java虚拟机内存->卸载):
- 加载
- 验证
- 准备
- 解析
- 初始化
- 使用
- 卸载
其中:加载,验证,准备,初始化,卸载五部的顺序是固定的。
二、类的加载过程:
- 加载:查找并加载类的二进制数据(class类)
- 方法区:类的类信息
- 堆:Class文件对应的类实例
- 验证:确保加载的类信息是正确的
- 准备:为类的静态变量进行初始化,分配空间并赋予初始值
- 解析:是将符号引用转换为直接引用
- 初始化:JVM对类进行初始化,对静态变量赋予正确值
- 静态代码块
三、类加载器分类:
-
BootstrapClassLoader启动类加载器):
- 负责加载JVM运行核心类(JDK\JRE\lib的java.xxx.xxx包路径),或者被-Xbootclasspath参数限定的类
- 加载System.getProperty(“类的全路径名”);所指定的路径或jar包
- c++编写,通过java打印不出结果
-
ExtClassLoader(扩展类加载器):
- 负责加载JVM的扩展类(JDK/JRE/lib/ext javax.xxx.xx包路径),比如Swing系列,内置的js引擎,xml解析器等,这些库 名通常以javax开头
- 或者是被java.ext.dirs指定的类
-
AppClassLoader(应用程序类加载器):
- 加载环境变量CLASSPATH路径下的包
- 我们自己编写的代码以及使用的第三方 jar 包通常都是由它来加载的。
-
URLClassLoader
那些位于网络上静态文件服务器提供的 jar 包和 class文件,jdk 内置了一个 URLClassLoader,用户只需要传递规范的网络路径给构造器,就可以使用 URLClassLoader 来加载远程类库了。URLClassLoader 不但可以加载远程类库,还可以加载本地路径的类库,取决于构造器中不同的地址形式。ExtensionClassLoader 和 AppClassLoader 都是 URLClassLoader 的子类,它们都是从本地文件系统里加载类库。
-
还可以自己写个自定义类加载器,通过集成ClassLoder实来现
四、双亲委派模型:
如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,一次向上,因此,所有的类加载请求最终都应该被传递到顶级的启动类加载器中,只有当父加载器在它的搜索范围中没有找到所需的类时,即无法完成该类的加载,子加载器才会尝试自己去加载该类。
为啥要这么做呢?
因为要保证只有一个类加载器加载类,不能所有的加载器都加载类,防止内存中出现多份同样的字节码。