Java的类载入器

转载自:https://blog.csdn.net/PacosonSWJTU/article/details/50800825

【0】README

0.1)本文文字转自: 深入剖析tomcat, 旨在 理解 jvm 的类载入器;

【1】 jvm的类载入器相关

1)jvm 使用了3种类载入器来载入所需要的类:分别是引导类载入器(bootstrap class loader), 扩展类载入器(extension class loader) 和 系统类载入器(system class loader)。而 引导类载入器是 扩展类载入器的父亲, 扩展类载入器是 系统类载入器的父亲。
2)3种载入器的详细描述:

  • 2.1)引导类载入器: 用于引导启动 jvm。当调用 javax.exe 是, 就会启动引导类载入器。引导类载入器是使用本地代码来实现的, 因为它用来载入运行 jvm 所需要的类, 以及所有的 java 核心类。如 java.lang 包 和 java.io 包下的类。启动类载入器会在 rt.jar 和 i18n.jar 等java 包中搜索要载入的类。
  • 2.2)扩展类载入器: 负责载入标准扩展目录中的类。sum 公司的 jvm 的标准扩展目录是 /jdk/jre/lib/ext/;
  • 2.3)系统类载入器:是默认的类载入器,他会搜索在环境变量 CLASSPATH 中指明的路径和 JAR 文件;

3)jvm 使用的是哪种类载入器呢?
3.1)答案在于 类载入器的代理模型。
3.2)载入一个类 的steps(每当需要载入一个类 的时候):

  • step1)首先调用 系统类载入器,但并不会立即载入这个类;
  • step2)相反,他会将载入类的任务交给其父类载入器——扩展类载入器;
  • step3) 而扩展类载入器也会将载入任务交给其父类载入器——引导类载入器;

3.3)因此,引导类载入器会首先执行载入某个类的任务。接下来有4中cases:

  • case1)如果引导类载入器找不到需要载入的类,那么扩展类载入器会尝试 载入该类;
  • case2)如果扩展类载入器也找不到该类,就轮到系统类载入器继续执行载入任务;
  • case3)如果系统类载入器也找不到这个类,抛出 ClassNotFoundException 异常;

3.4)为什么要这么做? 代理模型的重要用途就是为了 解决 类载入过程中的安全问题;

  • 看个例子: 当程序的某个地方调用了 自定义的 java.lang.Object 类时, 系统类载入器会将载入工作 委托给 扩展类载入器,继而会被交给 引导类载入器。 引导类载入器搜索其 核心库, 找到标准的 java.lang.Object 类, 并将之实例化。 结果是, 自定义的 java.lang.Object 类并没有被载入。幸运的是, jvm 我们使用了 代理模型, 这种case 是不会发生 的。

4)关于 java 中类载入机制的一件重要事情是, 可以通过继承抽象类 java.lang.ClassLoader 类 编写自己的类载入器。而 tomcat 要使用自定义类载入器的原因有3条(reasons):

  • r1) 为了在载入类中指定某些规则;
  • r2)为了缓存已经载入的类;
  • r3)为了实现类的预载入,方便使用;

猜你喜欢

转载自blog.csdn.net/hchhan/article/details/82355342