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
相关推荐
1. **引导类加载器(Bootstrap ClassLoader)**:这是最基础的类加载器,由JVM本身实现,主要负责加载JDK核心库,如rt.jar中的类,这些类通常位于JRE的lib目录下。 2. **扩展类加载器(Extension ClassLoader)**:由...
《深入Java虚拟机(七)深入源码看java类加载器ClassLoader》 Java类加载器(ClassLoader)在Java运行环境中扮演着至关重要的角色。它负责将类的字节码加载到Java虚拟机(JVM)中,使得程序能够运行。ClassLoader是...
3. Application ClassLoader:也称为系统类加载器,负责加载用户类路径`-cp`或`-classpath`指定的所有类。 当一个类被加载时,如果它的父类加载器无法加载该类,那么会将任务委派给子类加载器。这就是著名的"委托...
### Java ClassLoader (类加载器)详解 #### 一、教程提示 如果你正在查看这份文档,在线版中你可以点击下面的任何主题直接跳转到相应的部分。 1. **教程提示** 2. **介绍** 3. **类加载器结构** 4. **编译类加载...
Java类加载器分为三种主要类型:引导类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用程序类加载器(Application ClassLoader,也称为系统类加载器)。它们共同工作,确保了Java...
在 JVM 运行过程中,类加载器会形成一个层次结构,包括引导类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和系统类加载器(System ClassLoader)。 引导类加载器(Bootstrap ...
System.out.println("JDK提供的Object类由哪个类加载器加载--> " + classLoader); } ``` 从上述代码中可以看出,系统的类加载器是`AppClassLoader`,它的父加载器是`ExtClassLoader`,而`ExtClassLoader`的父加载...
**类加载器(ClassLoader)**是Java虚拟机(JVM)中的一个重要组成部分,它负责将编译好的`.class`文件加载到JVM中,使得这些类可以在Java环境中运行。类加载器不仅能够加载类,还能够根据不同的需求定制加载方式,如从...
这个过程可以由系统类加载器、自定义类加载器或者父类加载器完成。加载过程中,如果类已经被加载,那么就不会再次加载。 2. **验证**: 验证是确保.class文件的字节流符合JVM规范,防止恶意代码对系统的破坏。验证...
当一个类被加载时,它首先会尝试由当前线程的Context ClassLoader进行加载,如果该类加载器无法加载,则向上委托给父类加载器,直至Bootstrap ClassLoader。这种设计可以避免类的重复加载,同时保证核心库的稳定性和...
3. **Application ClassLoader** (应用程序类加载器): 也称为系统类加载器,负责加载用户定义的类路径上的类,通常通过`-classpath`或`-cp`命令行参数指定。 这三种类加载器之间存在层级关系,形成了所谓的“双亲...
4. **Webapp ClassLoader**:每个Web应用都有自己的类加载器,负责加载对应Web应用的WEB-INF/classes和WEB-INF/lib目录下的类和JAR文件。这种设计确保了不同Web应用间的类隔离,防止类冲突。 5. **Catalina ...
- Java中的类加载器采用双亲委派模型,即一个类首先由启动类加载器Bootstrap ClassLoader尝试加载,如果找不到则交给扩展类加载器Extension ClassLoader,再找不到则交由应用程序类加载器AppClassLoader,最后如果...
上述代码展示了如何创建一个自定义类加载器`MyClassLoader`,该类继承自`java.lang.ClassLoader`。`MyClassLoader`的主要功能是从文件系统中加载指定类的二进制数据。 - **构造函数**:接受一个父类加载器和基础...
类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一。它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java ...
类加载器遵循双亲委派模型,这意味着当一个类加载器尝试加载类时,它首先会将请求委托给其父类加载器,直到到达顶层的Bootstrap ClassLoader,如果父类加载器无法找到该类,子类加载器才会尝试自己加载。 在Tomcat...
以下是对类加载器的详细介绍: 1. 类加载机制: Java的类加载分为加载、验证、准备、解析和初始化五个阶段。加载阶段是类加载器的主要工作,它负责找到类的二进制表示并将其转化为Class对象。加载器按照双亲委派...
Java 类加载器 ClassLoader 用法解析 Java 中的类加载器(ClassLoader)是一种机制,负责将类从文件系统、JAR 文件或网络等来源加载到 Java 虚拟机中。类加载器的作用是将类的二进制数据加载到内存中,并为其创建一...
在Java编程语言中,类加载器(ClassLoader)是一个至关重要的组件,负责将类的字节码从磁盘、网络或其他数据源加载到JVM(Java虚拟机)中,然后将其转换为运行时的类对象。这个过程是Java程序动态加载和运行的基础。...
Java类加载器(ClassLoader)是Java虚拟机(JVM)中的一个重要组成部分,用于将Java类文件加载到JVM中,以便能够执行Java程序。在Java中,类加载器的设计采用了一种称为“双亲委派模式”(Parent Delegation Model)...