Java Class Loader的工作原理在宫力等人的《Inside Java 2 Platform Security》和Bill Venners的《Inside Java 2 Virturl Machine》里面有非常精彩的介绍。不过这个问题还是困惑了我一段时间,所以把心得小结如下。
JVM采用动态类型加载方式,所以概念上只有当一个类型被应用到时,虚拟机才会加载它。比如,假设类C引用了类D,只有当虚拟机执行到C中引用D的语句时才会去加载D。
Defining Class Loader 和 Initiating Class Loader
Defining class loader是指真正执行加载某个类的动作的那个类加载器实例。在虚拟机中,一个类型C是由其类型名和定义它的那个defining class loader来唯一标识的,即C=<N, L>。Iniating class loader是指发起这个加载动作的类加载器实例。比如在前面的例子中,虚拟机发现C引用D时,就把C的defining class loader作为D的initiating class loader。至于D最终是由谁定义的,则要由class loader的代理机制来决定。
常见Class Loader
文章和书籍中常常提到下面几种class loader:
- Bootstrap class loader:虚拟机运行时必须要用到的类的加载器,比如java.*。它通常是在虚拟机种用本地代码(如C)实现,在系统中用null表示。
- Extension class loader:负责加载Java环境中安装的可选包(optional package)中的类。
- Application class loader:负责加载CLASSPATH上的类。有时候也称为system class loader,Java程序可以通过调用java.lang.getSystemClassLoader()获得它的引用。
层次关系
Class loader之间有两种层次关系:继承关系和代理(delegation)关系。
除bootstrap class loader之外的所有其它class loader都是用Java语言来实现的,所以它们之间自然有继承关系。Java API里面定义的类的继承关系如下:java.net.URLClassLoader --> java.security.SecureClassLoader --> java.lang.ClassLoader --> java.lang.Object。
代理关系是class loader实例之间的动态关系。在创建一个class loader实例时可以给其构造函数传递一个parent参数,这样该parent就成了新创建的class loader在代理层次上的父节点。这个层次树的根节点就是bootstrap class loader实例。Java程序可以通过调用class loader实例的getParent()方法来获取其父节点。比如在JDK1.5中运行HelloWorld程序时class loader的代理继承关系如下:sun.misc.Launcher$AppClassLoader --> sun.misc.Launcher$ExtClassLoader --> null (bootstrap class loader)。
代理机制
当一个class loader收到加载某个类的请求时,它按照下面的流程处理:
- 查找这个类是不是已经被自己加载过,如果没有则进行下一步;
- 请求代理层次中的父加载器加载这个类;
- 如果父加载器无法加载这个类(抛回异常),则尝试自己加载这个类。如果能够加载,则定义该类,否则抛出异常。
所以在代理层次结构上的子节点永远只加载父节点(及其祖先节点)所不能加载的类,这样可以保证类始终被合适的class loader加载,比如rt.jar中的类永远被bootstrap class loader加载。
回到HelloWorld的例子。当虚拟机一开始加载HelloWorld类的时候,它的initiating class loader是application class loader,该类调用extension class loader,它又调用bootstrap class loader;bootstrap class loader(在rt.jar中)找不到HelloWorld类,抛出异常;extension class loader截获异常后开始试图自己加载,但是它(在扩展包内)也找不到HelloWorld,于是也抛出异常;application class loader截获这个异常,它在CLASSPATH中找到了HelloWorld于是加载并定义了这个类,所以HelloWorld类的defining class loader就是这个application class loader实例。
当HelloWorld引用到java.lang.System类时虚拟机开始加载System类。这时定义了HelloWorld类的application class loader就成了System类的iniating class loader。重复上述操作,但是这次bootstrap class loader找到了System类就定义了该类,后面的extension class loader和application class loader就不再试图加载了。所以java.lang.System类的defining class loader就是bootstrap class loader。
分享到:
相关推荐
遇到类冲突、类找不到等问题时,可通过设置JVM参数`-verbose:class`来查看类加载的详细信息,或者使用JDK的`jmap -histo`命令分析内存中的类加载情况。 8. **线程安全** 类加载过程中的某些步骤,如加载和初始化...
System.out.println("parent class loader: " + cl.getParent()); cl = cl.getParent(); } ``` 这段代码会打印出当前的类加载器以及它们的父加载器。通常,你会看到AppClassLoader(系统类加载器)、...
本工具是对java class文件进行加密保护的工具!本工具全面支持linux/unix/windows操作系统。 众所周知,java编译后的class文件是一种中间字节字文件, 很容易被反编译工具反编译,而传统的java源代码保护方法基本都是...
创建自定义类加载器通常需要继承`java.lang.ClassLoader`,重写`findClass()`或`loadClass()`方法,从而控制类的查找和加载过程。这使得开发者能够在运行时根据需要加载特定的类,比如从网络、数据库或其他非传统...
本工具是对java class文件进行加密保护防止反编译的工具!本工具全面支持linux/unix/windows操作系统。 继推出v1.0版本后,获得了用户大量的支持与的反馈,我们再次推出本v2.0版,对加密算法进行了更大的改进,安全...
JVM 负责执行 Java 字节码,Java Class Loader 负责加载类文件,而 Java Security Manager 则负责实施安全策略。 Java 安全协议 Java 安全协议是指 Java 平台使用的安全协议,包括 SSL/TLS、HTTPS 等。这些协议...
* Java Class Loader:Java Class Loader 负责加载和管理 Java 类文件。 * Java Native Interface(JNI):JNI 是 Java 平台标准版提供的一种机制,用于将 Java 代码与 native 代码集成。 4.Java 平台标准版的新...
2. Java Class Loader: Class Loader 负责加载和链接 Java 字节码,提供了类加载和解析的功能。 3. Java Native Interface(JNI): JNI 是 Java 平台和 native 代码之间的接口,提供了 Java 和 native 代码之间的...
本手册还涵盖了 Java SE 9 中的其他工具和命令,例如 Java 任务计划器(java)、Java Class Loader(java.lang.ClassLoader)等。 在本手册中,我们将详细介绍每个工具和命令的使用方法、参数设置和示例代码,以...
Java加载器(Loader)是Java虚拟机(JVM)的核心组成部分,主要负责将类的字节码文件加载到JVM中并转换为运行时的数据结构。在深入理解这个概念之前,我们首先要明白Java的类加载机制。Java的类加载过程包括加载、...
Java虚拟机(JVM)的Class文件原理是Java程序运行的基础。Java中的所有类都必须先被装载到JVM中才能被执行,这个过程由JVM内的类装载器(ClassLoader)来完成。类装载器的工作是将类文件从硬盘读取到内存中,使得JVM...
Java的Class类是Java反射机制的核心,它代表了Java中的每一个类和接口。Class类的主要功能是提供关于类的信息,包括类的结构、属性、方法等。以下是对Java Class类的详细说明: 1. **Class类对象的创建**:在Java中...
- `public class Actions { ... }` 主类定义,包含了所有的成员变量和方法。 #### 四、核心方法解析 1. **`init()`**:初始化方法负责加载配置文件、登录系统、初始化参数等基础工作。 - **配置加载**:`load_...
在Java编程语言中,类加载器(Class-Loader)是一个至关重要的组件,它负责加载类到JVM(Java虚拟机)中。这个“class-loader测试工程”可能是一个专门设计用于研究和理解Java类加载机制的项目。在Java中,类加载...
### 动态类加载在Java虚拟机中的应用 #### 概述 动态类加载是Java虚拟机(JVM)的一项核心特性,它为Java平台带来了强大的功能:即能够在运行时安装软件组件。这一机制不仅提高了系统的灵活性,还优化了资源管理。...
The Class Loader Architecture The Java Class File The Java API The Java Programming Language Architectural Tradeoffs Future Trends On the CD-ROM The Resources Page 2 Platform independence Why ...
`Class.forName`实际上依赖于当前线程的上下文类加载器(Context Class Loader)。如果类已经加载,`forName`会直接返回该类的`Class`对象;否则,它会使用当前线程的上下文类加载器来加载类。而`ClassLoader`通常...