ClassLoader加载Class的过程 解析

ClassLoader即类加载器,负责将 .class 文件(可能在磁盘上, 也可能在网络上) 加载到内存中, 并为之生成对应的 java.lang.Class 对象,当 JVM 启动时,会造成由三个类加载器组成的初始类加载器层次结构:bootstrap classloader ——> extension classloader ——> system classloaderjava

bootstrap classloader:引导(也称为原始)类加载器,它负责加载Java的核心类。这个加载器的是很是特殊的,它实际上不是 java.lang.ClassLoader的子类,而是由JVM自身实现的。能够经过执行如下代码来得到bootstrap classloader加载了那些核心类库:

bootstrap

[java] view plaincopy网络

  1. URL[] urls =sun.misc.Launcher.getBootstrapClassPath().getURLs();  jvm

  2. for(int i = 0 , i < urls.length ; i++){  url

  3. System.out.println(urls[i].toExternalForm());  spa

  4. }  操作系统


由于JVM在启动的时候就自动加载它们,因此不须要在系统属性CLASSPATH中指定这些类库.net

extension classloader -扩展类加载器,它负责加载JRE的扩展目录(JAVA_HOME/jre/lib/ext或者由java.ext.dirs系统属性指定的)中的JAR包。这为引入除Java核心类之外的新功能提供了一个标准机制。由于默认的扩展目录对全部从同一个JRE中启动的JVM都是通用的,因此放入这个目录的 JAR类包对全部的JVM和system classloader都是可见的。orm

extension classloader是system classloader的parent,而bootstrap classloader是extension classloader的parent,但 bootstrap classloader 不是一个实际的classloader。对象

system classloader - 系统(也称为应用)类加载器,它负责在JVM被启动时,加载来自在命令java中的-classpath或者java.class.path系统属性或者 CLASSPATH操做系统属性所指定的JAR类包和类路径。

能够经过静态方法ClassLoader.getSystemClassLoader()找到该类加载器。若是没有特别指定,则用户自定义的任何类加载器都将该类加载器做为它的父加载器。

classloader 加载类用的是全盘负责委托机制。

全盘负责:便是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的全部 Class也由这个classloader负责载入,除非是显式的使用另一个classloader载入

委托机制:先让parent(父)类加载器 (而不是super,它与parent classloader类不是继承关系)寻找,只有在parent找不到的时候才从本身的类路径中去寻找。

l类加载还采用了cache机制:若是 cache中保存了这个Class就直接返回它,若是没有才从文件中读取和转换成Class,并存入cache,这就是为何修改了Class可是必须从新启动JVM才能生效的缘由。

1. 检测此Class是否载入过(即在cache中是否有此Class),若是有到8,若是没有到2

2. 若是parent classloader不存在(没有parent,那parent必定是bootstrap classloader了),到4

3. 请求parent classloader载入,若是成功到8,不成功到5

4. 请求jvm从bootstrap classloader中载入,若是成功到8

5. 寻找Class文件(从与此classloader相关的类路径中寻找)。若是找不到则到7.

6. 从文件中载入Class,到8.

7. 抛出ClassNotFoundException.

8. 返回Class.

相关文章
相关标签/搜索