1,什么是ClassLoader
与 C 或 C++ 编写的程序不同,Java 程序并不是一个可执行文件,而是由许多独立的类文件组成,每一个文件对应于一个 Java 类。
此外,这些类文件并非立即全部都装入内存,而是根据程序需要装入内存。ClassLoader 是 JVM 中将类装入内存的那部分。
而且,Java ClassLoader 就是用 Java 语言编写的。这意味着创建您自己的 ClassLoader 非常容易,不必了解 JVM 的微小细节。
2,一些重要的方法
A)loadClass
ClassLoader.loadClass() 是ClassLoader的入口点。该方法的定义为:Class loadClass( String name, boolean resolve );
name:JVM 需要的类的名称,如 Foo 或 java.lang.Object。
resolve:参数告诉方法是否需要解析类。
B)defineClass
defineClass方法是ClassLoader的主要诀窍。该方法接受由原始字节组成的数组并把它转换成Class对象。
C)findSystemClass
findSystemClass方法从本地文件系统中寻找类文件,如果存在,就使用defineClass将原始字节转换成Class对象,以将该文件转换成类。
D)resolveClass
可以不完全地(不带解析)装入类,也可以完全地(带解析)装入类。当编写我们自己的loadClass时可以调用resolveClass,这取决于loadClass的resolve参数的值。
E)findLoadedClass
findLoadedClass充当一个缓存:当请求loadClass装入类时,它调用该方法来查看ClassLoader是否已装入这个类,这样可以避免重新装入已存在类所造成的麻烦。
3,Java2中ClassLoader的变动
1)loadClass的缺省实现
在Java2中loadClass的实现嵌入了大多数查找类的一般方法,并使您通过覆盖findClass方法来定制它,在适当的时候findClass会调用loadClass。
这种方式的好处是可能不一定要覆盖loadClass,只要覆盖findClass就行了,这减少了工作量。
2)新方法:findClass
loadClass的缺省实现调用这个新方法。
3)新方法:getSystemClassLoader
如果覆盖findClass或loadClass,getSystemClassLoader让我们以实际ClassLoader对象来访问系统ClassLoader,而不是固定的从findSystemClass 调用它。
4)新方法:getParent
为了将类请求委托给父ClassLoader,这个新方法允许ClassLoader获取它的父ClassLoader。
4,定制ClassLoader
其实我们或多或少都使用过定制的ClassLoader,因为Applet查看器中就包含一个定制的ClassLoader。
它不在本地文件系统中寻找类,而是访问远程服务器上的 Web 站点,经过 HTTP 装入原始的字节码文件,并把它们转换成JVM 内的类。
Applet查看器中的ClassLoader还可以做其它事情:它们支持安全性以及使不同的Applet在不同的页面上运行而互不干扰。
我们将写一个自己的ClassLoader实现示例,它将实现如下步骤,这也是ClassLoader的工作原理:
# 调用 findLoadedClass 来查看是否存在已装入的类。
# 如果没有,那么采用那种特殊的神奇方式来获取原始字节。
# 如果已有原始字节,调用defineClass将它们转换成Class对象。
# 如果没有原始字节,然后调用findSystemClass查看是否从本地文件系统获取类。
# 如果resolve参数是true,那么调用resolveClass解析Class对象。
# 如果还没有类,返回ClassNotFoundException。
# 否则,将类返回给调用程序。
话不多说,看看代码先:
FileClassLoader.java:
代码
- import java.io.ByteArrayOutputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
-
- public class FileClassLoader extends ClassLoader {
- public Class findClass(String name) {
- byte[] data = loadClassData(name);
- return defineClass(name, data, 0, data.length);
- }
-
- private byte[] loadClassData(String name) {
- FileInputStream fis = null;
- byte[] data = null;
- try {
- fis = new FileInputStream(new File("D:\\project\\test\\" + name + ".class"));
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- int ch = 0;
- while ((ch = fis.read()) != -1) {
- baos.write(ch);
- }
- data = baos.toByteArray();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return data;
- }
- }
<script type="text/javascript"></script>
MyApp.java:
代码
- public class MyApp {
- public static void main(String[] args) throws Exception {
- FileClassLoader loader = new FileClassLoader();
- Class objClass = loader.findClass("MyApp");
- Object obj = objClass.newInstance();
- System.out.println(objClass.getName());
- System.out.println(objClass.getClassLoader());
- System.out.println(obj);
- }
- }
<script type="text/javascript"></script>
编译并运行MyApp类,结果为:
代码
分享到:
相关推荐
NULL 博文链接:https://lz12366.iteye.com/blog/735289
Sun 官方关于 ClassLoader原理的文章,值得一看
Java 虚拟机中ClassLoader 相关简介 双亲委托机制 Android 中ClassLoader 简介
ClassLoader运行机制 自己写的ClassLoader运行机制 自己写的ClassLoader运行机制 自己写的ClassLoader运行机制 自己写的ClassLoader运行机制 自己写的
自定义classloader的使用
破解java加密的ClassLoader.java,在classloader植入破解代码
ClassLoader原理,ClassLoader原理 ClassLoader原理
Java ClassLoader定制实例
java classloader classpath 张孝祥
关于J2EE服务器的ClassLoader的原理,该文档清晰了揭示了jvm装载类的顺序,同时用户可以自定义修改classLoader的配置 通过该文档,可以加深对Java虚拟机的理解
理解Java ClassLoader机制
用于验证理解Android中Classloader加载类机制的程序demo,从中可以对比DexClassLoader和PathClassLoader的区别联系。
Classloader
ClassLoader类加载机制和原理详解
classloader 源码,自定义classloader
自定义ClassLoader,控制台输入调试。 运行期间 重新载入指定目录的class文件。可实现对于类的功能函数更新。 用到java 反射,@interface 等技术
Java中ClassLoader的解析,从ClassLoader的角度分析了JVM,装载类,创建类的对象的整个过程,更清晰的了解JVM的运行机制。
JVM内存模型,类加载模式工作机制详细,内存屏障,类从被加载到虚拟机内存中开始,直到卸载出内存为止,它的整个生命周期包括了:加载、验证、准备、解析、初始化、使用和卸载这7个阶段。其中,验证、准备和解析这三...