写点什么

JVM - 类加载器

用户头像
insight
关注
发布于: 2021 年 03 月 21 日

作用:负责将 class 加载进入 JVM 中,审查每个类由谁加载。对于用户而言,最大的好处是实现类的动态加载操作。


产生原因:由于 class 类提供的 forName() 方法只能加载 .CLASSPATH 中的类,而类的加载路径则有可能在网络、文件、数据库中,因此需要类加载器


获取:通过调用 Class 类中的 getClassLoader( )方法即可获取一个 ClassLoader


分类

一、虚拟机自带的加载器

  • 启动类加载器(Bootstrap ClassLoader):由 C++ 编写,引擎加载器(核心加载器),负责加载核心 JAVA 类(即所有 java.*开头的类)。如 java.lang中的类。

  • 扩展类加载器(Extension ClassLoader):由 Java 编写,负责加载在拓展库下的类——拓展的 JAVA 类 和 第三方程序类库。(例如所有 javax.*开头的类和存放在 JRE 的 ext 目录下的类)

  • 应用程序类加载器(Application ClassLoader):也叫系统类加载器,由 Java 编写,加载应用程序自身的类(即程序猿编写的类),如当前应用中 CLASSPATH 中的所有类


上面这三个加载器是一个继承关系:AppClassLoader->Extension->Bootstrap(->代表继承)


二、用户自定义加载器

java.lang.ClassLoader的子类,用户可以定制类的加载方式。


产生的原因:


  • 一方面是由于 java 代码很容易被反编译,如果需要对自己的代码加密的话,可以对编译后的代码进行加密,然后再通过实现自己的自定义类加载器进行解密,最后再加载。

  • 另一方面也有可能从非标准的来源加载代码,比如从网络来源,那就需要自己实现一个类加载器,从指定源进行加载。

双亲委派机制

定义

某个特定的类加载器在接到加载类的请求时


  1. 首先将加载任务委托给父类,依次递归

  2. 如果父类加载器可以完成类加载的任务,就成功返回

  3. 只有父类加载器都无法完成加载任务时,才自己去加载。


比如,当加载一个 Person.class 的时候,加载这个类的请求会由 Application 类加载器委托给它的父类加载器 Extension 类加载器,然后 Extension 类加载器会将请求委托给 Bootstrap 类加载器,Bootstrap 类加载器会在 rt.jar 包中检查是否有这个类,如果有则返回,如果没有则将请求返回给 Extension 类加载器,Extension 类加载器会查看 jre/lib/ext 这个目录,如果没有,则返回给 Application 类加载器,Application 类加载器会在当前项目的 classpath 中进行寻找,如果没找到,则会抛出异常。


原因:为了保证 java 的沙箱机制,通过这种方式,会优先使用 Java 自身的类,这样可以防止恶意代码对 Java 的破坏,如通过编写常用类的同名类,来骗过程序员,由此来获取一些私密数据。


用户头像

insight

关注

不要混淆行动与进展、忙碌与多产。 2018.11.17 加入

永远都是初学者

评论

发布
暂无评论
JVM - 类加载器