类加载器
与普通程序不同的是,Java程序(class文件)并不是本地的可执行程序。当运行Java程序时,首先运行JVM,然后再把Java class加载到JVM里头运行,负责加载Java class的这部分就叫做Class Loader。
类加载器负责将 .class 文件(可能在磁盘上, 也可能在网络上) 加载到内存中, 并为之生成对应的 java.lang.Class
对象当 JVM 启动时,会形成由三个类加载器组成的初始类加载器层次结构:
BootStrap-->ExtClassLoader-->AppClassLoader
类加载器本生又是一个java对象,每个类加载器负责加载特点位置的类
一般类加载器的加载过程如下:
调用 findLoadedClass() 来查看是否存在已装入的类。
如果没有,那么获取class文件的原始字节。(通过IO从文件系统,来自网络的字节流等)
如果已有原始字节,调用 defineClass() 将它们转换成 Class 对象。
如果没有原始字节,然后调用 findSystemClass() 查看是否从本地文件系统获取类
如果 resolve 参数是 true,那么调用 resolveClass() 解析 Class 对象。
如果还没有类,返回 ClassNotFoundException。 否则,将类返回给调用程序。
三者的关系
Application ClassLoader的Parent是Extension ClassLoader,
而Extension ClassLoader的Parent为Bootstrap ClassLoader。
加载一个类时,首先BootStrap进行寻找,找不到再由Extension ClassLoader寻找,最后才是Application ClassLoader。
bootstrap classloader
bootstrap classloader:引导(也称为原始)类加载器,它负责加载Java的核心类。这个加载器的是非常特殊的,它实际上不是 java.lang.ClassLoader的子类,而是由JVM自身实现的。JVM在启动的时候就自动加载它们,不需要在系统属性CLASSPATH中指定这些类库。
extension classloader
extension classloader -扩展类加载器,它负责加载JRE的扩展目录(JAVA_HOME/jre/lib/ext或者由java.ext.dirs系统属性指定的)中的JAR包。
extension classloader是system classloader的parent,
而bootstrap classloader是extension classloader的parent,
但 bootstrap classloader 不是一个实际的classloader。
system classloader
system classloader - 系统(也称为应用AppClassLoader)类加载器,它负责在JVM被启动时,加载来自在命令java中的-classpath或者java.class.path系统属性或者 CLASSPATH操作系统属性所指定的JAR类包和类路径。
可以通过静态方法ClassLoader.getSystemClassLoader()找到该类加载器。如果没有特别指定,则用户自定义的任何类加载器都将该类加载器作为它的父加载器。
加载器的全盘负责委托机制
classloader 加载类用的是全盘负责委托机制,集中管理,不会相同的多份字节码。
全盘负责:即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有 Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入委托机制:先让parent(父)类加载器 (而不是super,一直向上直到BootStrap类加载器)寻找,只有在parent找不到的时候才从自己的类路径中去寻找。
类加载还采用了cache机制:如果 cache中保存了这个Class就直接返回它,如果没有才从文件中读取和转换成Class,并存入cache,这就是为什么修改了Class但是必须重新启动JVM才能生效的原因。
ClassLoader加载Class的过程
1. 检测此Class是否载入过(即在cache中是否有此Class),如果有到8,如果没有到2
2. 如果parent classloader不存在(没有parent,那parent一定是bootstrap classloader了),到4
3. 请求parent classloader载入,如果成功到8,不成功到5
4. 请求jvm从bootstrap classloader中载入,如果成功到8
5. 寻找Class文件(从与此classloader相关的类路径中寻找)。如果找不到则到7.
6. 从文件中载入Class,到8.
7. 抛出ClassNotFoundException.
8. 返回Class.
类加载器之间关系和管辖范围
根BootStarp -->jre/lib/rt.jar
扩展ExtClassLoader-->jre/lib/ext/*.jar
应用AppClassLoader-->classpath指定的所有jar或目录
public class Test {
public static void main(String[] args) {
ClassLoader loader = Test.class.getClassLoader();
while(loader!=null){
System.out.println(loader.getClass().getName());
loader = loader.getParent();
}
System.out.println(loader);
//null表示加载器为BootStrap,BootStrap是有C++程序编写的,是最根上的类器。
//java核心类都是由BootStrap类加载器加载的,对应的jar包是jre/lib/rt.jar
String t = Test.class.getClassLoader().getClass().getName();
System.out.println(t);//加载器为AppClassLoader
//当把此类的的Class文件打成jar包后放置在jdk安装目录下的jre/lib/ext(扩展包)时
//类加载器为ExtClassLoader, 这是由类加载器的委托机制决定的
}
}
分享到:
相关推荐
《深入Java虚拟机(七)深入源码看java类加载器ClassLoader》 Java类加载器(ClassLoader)在Java运行环境中扮演着至关重要的角色。它负责将类的字节码加载到Java虚拟机(JVM)中,使得程序能够运行。ClassLoader是...
System.out.println("JDK提供的Object类由哪个类加载器加载--> " + classLoader); } ``` 从上述代码中可以看出,系统的类加载器是`AppClassLoader`,它的父加载器是`ExtClassLoader`,而`ExtClassLoader`的父加载...
Java 类加载器 ClassLoader 用法解析 Java 中的类加载器(ClassLoader)是一种机制,负责将类从文件系统、JAR 文件或网络等来源加载到 Java 虚拟机中。类加载器的作用是将类的二进制数据加载到内存中,并为其创建一...
1. **引导类加载器(Bootstrap ClassLoader)**:这是最基础的类加载器,由JVM本身实现,主要负责加载JDK核心库,如rt.jar中的类,这些类通常位于JRE的lib目录下。 2. **扩展类加载器(Extension ClassLoader)**:由...
3. Application ClassLoader:也称为系统类加载器,负责加载用户类路径`-cp`或`-classpath`指定的所有类。 当一个类被加载时,如果它的父类加载器无法加载该类,那么会将任务委派给子类加载器。这就是著名的"委托...
### Java ClassLoader (类加载器)详解 #### 一、教程提示 如果你正在查看这份文档,在线版中你可以点击下面的任何主题直接跳转到相应的部分。 1. **教程提示** 2. **介绍** 3. **类加载器结构** 4. **编译类加载...
Java类加载器分为三种主要类型:引导类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用程序类加载器(Application ClassLoader,也称为系统类加载器)。它们共同工作,确保了Java...
Java的ClassLoader类加载器机制 在 Java 虚拟机(JVM)中,类加载器(ClassLoader)扮演着非常重要的角色。类加载器负责加载 Java 类,包括核心类和用户自定义类。在 JVM 运行过程中,类加载器会形成一个层次结构,...
// static ClassLoader getSystemClassLoader():返回用于委派的系统类加载器 ClassLoader c = ClassLoader.getSystemClassLoader(); System.out.println(c); // AppClassLoader // ClassLoader getParent():...
**类加载器(ClassLoader)**是Java虚拟机(JVM)中的一个重要组成部分,它负责将编译好的`.class`文件加载到JVM中,使得这些类可以在Java环境中运行。类加载器不仅能够加载类,还能够根据不同的需求定制加载方式,如从...
这个过程可以由系统类加载器、自定义类加载器或者父类加载器完成。加载过程中,如果类已经被加载,那么就不会再次加载。 2. **验证**: 验证是确保.class文件的字节流符合JVM规范,防止恶意代码对系统的破坏。验证...
3. **Application ClassLoader** (应用程序类加载器): 也称为系统类加载器,负责加载用户定义的类路径上的类,通常通过`-classpath`或`-cp`命令行参数指定。 这三种类加载器之间存在层级关系,形成了所谓的“双亲...
开发者可以通过继承java.lang.ClassLoader类,创建自己的类加载器。这在处理动态加载、插件系统、隔离应用域等场景时非常有用。自定义类加载器需要覆盖`findClass()`方法,实现类的查找和加载逻辑。 4. 双亲委派...
当一个类加载器接收到加载类的请求时,它首先会委托其父类加载器去尝试加载,如果父类加载器无法加载,再由当前加载器尝试。这个过程一直向上,直到Bootstrap类加载器,如果Bootstrap也无法加载,再回退到原始的类...
- Java中的类加载器采用双亲委派模型,即一个类首先由启动类加载器Bootstrap ClassLoader尝试加载,如果找不到则交给扩展类加载器Extension ClassLoader,再找不到则交由应用程序类加载器AppClassLoader,最后如果...
4. **Webapp ClassLoader**:每个Web应用都有自己的类加载器,负责加载对应Web应用的WEB-INF/classes和WEB-INF/lib目录下的类和JAR文件。这种设计确保了不同Web应用间的类隔离,防止类冲突。 5. **Catalina ...
上述代码展示了如何创建一个自定义类加载器`MyClassLoader`,该类继承自`java.lang.ClassLoader`。`MyClassLoader`的主要功能是从文件系统中加载指定类的二进制数据。 - **构造函数**:接受一个父类加载器和基础...
在Java编程中,类加载器(ClassLoader)是一个关键组件,负责加载类到JVM(Java虚拟机)中。`ClassLoaderTest`是一个特定的测试用例,专注于如何有效地管理和关闭类加载器,以防止资源泄漏,特别是针对加载了基础jar...
类加载器遵循双亲委派模型,这意味着当一个类加载器尝试加载类时,它首先会将请求委托给其父类加载器,直到到达顶层的Bootstrap ClassLoader,如果父类加载器无法找到该类,子类加载器才会尝试自己加载。 在Tomcat...
类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一。它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java ...