类加载器

Posted miaooooo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类加载器相关的知识,希望对你有一定的参考价值。

类加载器:

实现 "通过类的全限定名获取描述此类的二进制字节流" 动作(类加载阶段)的模块。

判断两个类是否相等:类来自相同的 class 文件 && 被同一个虚拟机加载 && 由同一个类加载器加载。

类加载器的种类:

对虚拟机来说,只有启动类加载器(Bootstrap ClassLoader,由 C++ 实现,是虚拟机的一部分)和其他类加载器(由 Java 语言实现,独立于虚拟机外部,都继承自 java.lang.ClassLoader)。

1、启动类加载器(Bootstrap ClassLoader):

负责将 <JAVA_HOME>lib 目录中的、或者 Xbootclasspath 参数所指定的路径中的,并且是虚拟机识别的类库加载到虚拟机的内存中;无法被应用程序直接引用;

2、扩展类加载器(Extension ClassLoader):

负责加载 <JAVA_HOME>libext 目录中的、或者 java.ext.dirs 系统变量所指定的路径中的所有类库;可以直接使用扩展类加载器;

3、应用程序加载器(Application ClassLoader):

加载用户类路径(Class Path)上所指定的类库,如果应用程序没有自定义加载器,这个就是程序中默认的类加载器。

 

双亲委派模型(Parents Delegation Model):

除了启动类加载器,每个类加载器都有自己的父类加载器,此处的父子关系使用组合来复用父类加载器的代码。

工作过程:

如果一个类加载器收到类加载的请求,它首先把这个请求委派给父类加载器去完成,每一层的类加载器都是如此,即:所有的加载请求都应该传送到最顶层的启动类加载器,只有当父加载器反馈自己无法完成这个加载请求时,子类加载器才会尝试自己加载。

双亲委派模型如何保护可信任类库(lib、ext 文件夹中的类库)?

1、假设用户自己编写了一个 java.lang.Integer 的类,放在 ClassPath 中,则应用程序加载器在加载该类时,将不会加载成功(编译成功),应用程序加载器只会使用父类加载器返回的 java.lang.Integer 类。

2、假设用户自己编写了另外一个 java.lang.Integer2 的类,暗示该类是 java.lang 包中的类,尝试在 Integer2 类中访问 java.lang 包中的其他可信任的类并进行了一些破坏操作,此时该类会被应用程序加载器加载成功(因为启动类加载器、扩展类加载器都无法找到该类),但 "破坏操作" 是不会成功的。因为 java.lang.Integer2 类没有 java.lang 包中任何类的访问权限!为什么没有访问权限呢?因为 java.lang 包中可信任的类和 java.lang.Integer2 不属于同一个运行时包。

 

运行时包:

由同一个类装载器装载的、属于同一个包的、多个类型的集合。

在允许两个类型之间对包内可见成员进行访问之前,虚拟机不但要确定这两个类型属于同一个包,还必须确认它们由同一个加载器加载。

以上是关于类加载器的主要内容,如果未能解决你的问题,请参考以下文章

在 CI 模板加载器类中加载一个或多个视图

Java 类加载器

类加载器

深入理解Java虚拟机——类加载机制

类加载器

类加载器