Class Loader 名为“类加载器”,用以加载class 文件到Java 虚拟机中。与普通程序不同,class 文件(Java 程序)并不是本地的可执行程序。当运行class 文件时,首先会运行Java 虚拟机(以下简称JVM),然后再将class 文件加载至JVM,最后JVM 通过内部机制将其执行。负责加载class 文件的这部分程序即被称为"Class Loader"。
默认情况下,一个Java2 JVM通常提供了一个引导类加载器(Bootstrap Class Loader)和两个用户自定义的类装载器:扩展类加载器(Extension Class Loader)和系统/应用类加载器(System Class Loader/Application Class Loader)。
Bootstrap Class Loader 是负责加载JVM 的核心Java 类(如Java.* javax.*等)。Extension Class Loader 负责加载JRE 的扩展目录类。最后,System Class Loader 负责从系统类路径加载类。除了以上三种Class Loader 之外,用户还可以自定义Class Loader,自定义Class Loader是通过继承java.lang.ClassLoader 类来实现的,下面是几种Class Loader 的详细工作内容:
1).Bootstrap Class Loader
主要负责JRE_HOME(JRE 所在目录)/lib 目录下的核心API 或-Xbootclasspath 选项指定的jar包装入工作。
2).Extension Class Loader
主要负责JRE_HOME/lib/ext 目录下的jar 包或-Djava.ext.dirs 选项指定目录下的jar 包装入工作。
3).System/Application Class Loader
主要负责java -classpath 或-Djava.class.path 所指定目录下的class 与jar 包装入工作。
4).User Custom Class Loader(java.lang.ClassLoader的子类)
在程序运行期间, 通过自定义Class Loader 动态加载class 文件, 体现Java 语言动态实时类装入的特性。
四种Class Loader是逐级向上委托的关系,即4-->3-->2-->1 他们的关系如图所示:
这种向上依赖的关系模型被称作:双亲委托模型(或类似叫法,本文以JVM 实现为例),从Java2 (Java1.2版本)开始,Java引入了此种模型。
在此模型下,当一个装载器被请求装载某个类时,它首先委托自己的parent 去装载,若parent 能够装载,则返回这个类所对应的Class 对象,若parent 无法装载,则由parent 的请求者自行去装载。
采用此种模型可以避免重复加载,当上级Class Loader 已经加载了该类的时候,下级Class Loader就没有必要再加载一次。
我们来看一下JDK中java.lang.ClassLoader类加载类部分的源码:
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // First, check if the class has already been loaded Class c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); c = findClass(name); // this is the defining class loader; record the stats sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; } }
从代码中我们可以清晰的看到,在加载类的过程中会先判断改加载器有没有父类,如果有尝试用父类加载,如果加载不成功则自己加载。
考虑到安全因素,如果不使用这种委托模式,那我们就可以随时使用自定义Class Loader 重复加载Java 核心类,并修改相应内容。采用此种模式后,例如String,Integer等核心类将在JVM 启动之后自动被加载,用户将无法再去加载相关内容。从而防止了用户用恶意代码代替JVM 系统可靠代码的安全问题。
注意:此处所指parent 、上级、下级、父、子与Java中的继承不同,是一种逻辑依赖关系。
本文以JVM ClassLoader 实现为例未考虑其他特殊情况。
可以通过以下代码来验证一下这个模型:
public class HelloWorld { public static void main(String[] args) throws InterruptedException { ClassLoader loader = HelloWorld.class.getClassLoader(); int i=1; while (loader != null) { System.out.println(i+++":"+loader.getClass().getName()); loader = loader.getParent(); } System.out.println(loader); } }
2:sun.misc.Launcher$ExtClassLoader
null
相关推荐
java应用程序类加载器(ClassLoader for java Application),类似exe4j, 方便启动java程序, 配置灵活,支持多平台选择性配置
ClassLoader的API使用和自定义
ClassLoader类加载器讲解,理解JAVA类加载机制
类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一。它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java ...
如果户创建的JAR放在此录下,也会动由扩展类加载器加载.应程序类加载器(系统类加载器,Application ClassLoader)java语编写,由sun.
主要介绍了Java类加载器ClassLoader用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
关于类加载器的 上课ppt -java虚拟机自带的加载器 根类加载器(Bootstrap) c++写的看不到扩展类加载器(extension) 系统类加载器(System) AppClassLoad 用户自定义的类加载器 Java.lang.ClassLoader的子类
类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一。它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java ...
摘要视图订阅曹胜欢欢迎关注微信账号:java那些事:csh624366188.每天一篇java相关的文章登录 | 注册Java程序员从笨鸟到菜鸟(81)3054
【图解版】深入分析ClassLoader类加载工作机制,从原理到JVM的装载过程,详情分析了ClassLoader加载类以及自定义类加载器的过程,不可用于商业用途,如有版权问题,请联系删除!
3-7Tomcat中自定义类加载器的使用与源码实现(1).mp4
下面小编就为大家带来一篇classloader类加载器_基于java类的加载方式详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
jvm运行的过程中,需要载入类,而类的加载需要类加载器,本文章提供了java的类加载器的工作原理。可以使读者更加理解jvm的运行机制。
类加载器是Java最强大的特征之一。但是开发者常常忘记类加载组件。类加载器是在运行时负责寻找和加载类文件的类。Java允许使用不同的类加载器,甚至自定义的类加载器。类加载器从源文件(通常是.class 或 .jar文件)...
简单的自定义类加载器问候世界hello word,基于磁盘的ClassLoader
ClassLoader 三种类加载方式 Boostrap Extenxsion 以及Application ClassLoad分别适用的场景
Java的类加载机制:加载,连接,初始化。JAVA类加载器: Bootstrap ClassLoader : 根类加载器, Extension ClassLoader: 扩展类加载器, System ClassLoader : 系统类加载器, Java反射
JDK(Java Development Kit) 是 Java 语言的软件开发工具包(SDK)。 SE(J2SE),standard edition,标准版,是我们通常用的一个版本,从JDK 5.0开始,改名为Java SE。
类加载器分为根加载器(bootstrap classloader)、扩展类加载器(ext classloader)、系统类加载器(system classloader)、自定义类加载器(通常继承java.net.URLClassLoader,重写findClass()),它们的关系通常...
一个开源的Cplusplus类加载器,基于它实现了一个简单的例子,见我写的classloader的文章。