Java和其他语言不同的是,Java是运行于Java虚拟机(JVM)。这就
意味着编译后的代码是以一种和平台无关的格式保存的,而不是某种特定的机器上运行的格式。这种格式和传统的可执行代码格式有很多重要的区别。具体来说,不
同于C或者C++程序,Java程序不是一个独立的可执行文件,而是由很多分开的类文件组成,每个类文件对应一个Java类。
另外,这些类文件并不是马上加载到内存,而是当程序需要的时候才加载。
类加载器就是Java虚拟机中用来把类加载到内存的工具。而且,Java类加载器也是用Java实现的。这样你就不需要对Java虚拟机有深入的理解就可
以很容易创建自己的类加载器了。
为什么要创建类加载器?
既然Java虚拟金已经有了类加载器,我们还要自己创建其他的呢?问得好。默认的类加载器只知道如何从本地系统加载类。当你的程序完全在本机编译的话,默认的类加载器一般都工作的很好。但是Java中最激动人心的地方之一就是很容易的从网络上而不只是本地加载类。
举个例子,浏览器可以通过自定义的类加载器加载类。 还有很多加载类的方式。除了简单的从本地或者网络外,你还可以通过自定义Java中最激动人心的地方之一:
* 执行非信任代码前自动验证数字签名
* 根据用户提供的密码解密代码
* 根据用户的需要动态的创建类
你关心的任何东西都能方便的以字节码的形式集成到你的应用中
自定义类加载器的例子
如果你已经使用过JDK(Java软件开发包)中的appletviewer(小应用程序浏览器)或者其他
Java嵌入式浏览器,你就已经使用了自定义类加载器了。Sun刚刚发布Java语言的时候,最令人兴奋的一件事就是观看Java如何执行从远程网站下载
的代码。执行从远程站点通过HTTP连接传送来的字节码看起来有点不可思议。之所以能够工作,因为Java有安装自定义类加载器的能力。小应用程序浏览器
包含了一个类加载器,这个类加载器不从本地找Java类,而是访问远程服务器,通过HTTP加载原始字节码文件,然后在Java虚拟机中转化为Java
类。当然类加载器还做了其他的很多事情:他们阻止不安全的Java类,而且保持不同页面上的不同小程序不会互相干扰。Luke
Gorrie写的一个包Echidna是一个开放的Java软件包,他允许在一个Java虚拟机中安全的运行多个Java应用程序。它通过使用自定义类加
载器给每个应用程序一份类文件的拷贝来阻止应用程序之间的干扰。
java类加载器 :
java中默认有三种类加载器:引导类加载器,扩展类加载器,系统类加载器(也叫应用类加载器)
类加载器是Java最强大的特征之一。但是开发者常常忘记类加载组件。类加载器是在运行时负责寻找和加载类文件的类。Java允许使用不同的类加载器,甚至自定义的类加载器。
Java
程序包含很多类文件,每一个都与单个Java类相对应,这些类文件不像静态C程序,一次性加载入内存,它们随时需要随时加载。这就是类加载器与众不同的地
方。它从源文件(通常是.class 或
.jar文件)获得不依赖平台的字节码,然后将它们加载到JVM内存空间,所以它们能被解释和执行。默认状态下,应用程序的每个类由
java.lang.ClassLoader加载。因为它可以被继承,所以可以自由地加强其功能。
使用自定义类加载器的原因
默认的
java.lang.ClassLoader仅仅可以从加载本地文件系统的类。Java被设计成不论本地磁盘或网络都有足够的弹性加载类,并且可以在加载
之前处理特殊事物。例如:应用程序可以检查Web站点或FTP上插入类的更新版本并且自动校验数字签名确保执行可信任的代码。许多众所周知的软件都使用自
己的类加载器。
通常默认加载器是所谓的bootstrap类加载器;它负责加载诸如
java.lang.Object等关键类和加
载其他rt.jar文件的运行时代码到内存。因为Java语言规范没有提供bootstrap类加载器的详细信息,不同的JVM可能有不同的类加载器。如
果看到网页上有applets在运行,则它使用的是自定义类加载器。嵌入到浏览器中的applet阅读器包含了可以访问远程服务器上站点的类加载器,它可
以通过HTTP加载原始字节码文件,并且在JVM中将它们转换成类。
类加载器(除了bootstrap类加载器)有父类加载器,这些父类是基本
加载器的加载器实例。最重要的一点是设置正确的父加载器。然后可以使用
类加载器的getParent()方法实现委派类请求(例如:自定义类加载器找不到使用专门方法的类时)。此时必须为将父加载器作为
java.lang.ClassLoader构造器的参数:
public class MyClassLoader extends ClassLoader{
public MyClassLoader() {
super(MyClassLoader.class.getClassLoader());
}
}
loadClass(String
name)方法是ClassLoader的入口。名字参数是完全资格类名(FQCN),例如关于包类名。如果父加载器设置正确,当请求
MyClassLoader中的loadClass(String
name)方法加载类,但又找不到需要加载的类时,则首先会询问父加载器。如果父加载器也找不到此类,则调用findClass(String
name)方法。默认状态下findClass(String
name)会抛出ClassNotFoundException例外,很多开发人员都很清楚这个例外。自定义类加载器的开发者都希望从
java.lang.ClassLoader继承时跳过这个方法。
findClass()方法的目标是为MyClassLoader容纳所有专门
代码,此时不需要重复其他代码(例如当加载失败时调用系统
ClassLoader)。在此方法中,ClassLoader需要从原文件中获取字节码。一旦找到字节码则会调用defineClass()方法。
ClassLoader实例调用此方法是非常重要的。因此,如果两个ClassLoader实例定义了来自不同或相同原文件的字节码,则被定义的类也将区
别对待。
我们给出两个相似的类加载器MyClassLoader1 和
MyClassLoader2,它们都可以从相同的源文件找到MyCoolClass字节码。如果一个程序通过这两个加载器分别独立加载
MyCoolClass实例(coolClass1通过MyClassLoader1加载,
coolClass2通过MyClassLoader2加载),MyCoolClass.class能够被独立定义。执行下面的代码:
MyCoolClass coolClass1 = (MyCoolClass)coolClass2;
将得到一个ClassCastException例外。(开发者如果没有很
好的理解类加载机制则经常碰到这样的情况。)因为它们是不同的加载器
所定义的,JVM将它们看成不同的类。虽然它们是相同类型的类并且从相同的源文件加载,但是变量coolClass1和coolClass2不兼容。
不论是否跳过findClass() 或
loadClass(),getSystemClassLoader()方法将以实际ClassLoader对象的形式直接访问系统
ClassLoader。也可以通过调用findSystemClass(String
name)方法间接访问。getParent()方法允许获得父加载器。Listing A给出了可以运行的自定义类加载器示例。
本文来自CSDN博客,转载请标明出处:
http://blog.csdn.net/zdwzzu2006/archive/2008/04/05/2253982.aspx
分享到:
相关推荐
在Java中,类加载器分为三种类型:BootstrapClassLoader(启动类加载器)、ExtensionClassLoader(扩展类加载器)和ApplicationClassLoader(应用程序类加载器)。这些类加载器并不是继承关系,而是通过组合关系复用...
类加载机制不仅涉及到类的加载、验证、准备、解析和初始化等步骤,还包括类加载时机的选择及类加载器的具体工作原理等内容。 #### 一、类加载时机 Java类的生命周期主要包括以下几个阶段:加载、验证、准备、解析...
理解类加载器的工作原理对于深入学习Java平台、优化应用程序性能以及实现自定义加载器至关重要。 1. **类加载器层次结构** Java中的类加载器分为三个主要层次:启动类加载器(Bootstrap ClassLoader)、扩展类加载...
1. Bootstrap ClassLoader(启动类加载器):它是用C++实现的,是Java类加载层次中最顶层的类加载器,主要负责加载Java运行时环境的核心类库,例如`java.*`包下的类。由于是用C++实现的,它不是Java类,因此在Java中...
为了实现这个目标,需要对 Java 类加载器的体系结构、动态类加载机制原理、实现过程和实现方法进行分析。 Java 类加载器是 Java 虚拟机(JV M)的一部分,负责加载 Java 类文件并将其转换为可执行代码。 Java 类...
总结来说,Java类加载机制是JVM的基础,理解其原理有助于优化程序性能和排查问题;而SPI机制是Java平台提供的一种灵活的服务发现和加载方式,它促进了模块化开发和插件化的实现,增强了软件的可扩展性。这两个知识点...
这篇博文“JAVA类加载器分析--热部署的缺陷”探讨了Java类加载机制以及在热部署场景下可能遇到的问题。热部署允许开发者在不重启应用的情况下更新代码,提高开发效率,但同时也存在一些挑战。 首先,我们来理解类...
Java类加载机制实现流程及原理详解 Java类加载机制是Java虚拟机(JVM)的一部分,它负责将类的二进制数据加载到内存中,并对其进行验证、准备、解析和初始化,以形成可以被JVM直接使用的Java类型。下面是Java类加载...
WebLogic的主要类加载器包括Bootstrap类加载器、Extension类加载器、Application类加载器以及Domain类加载器等。 2. **Bootstrap类加载器** Bootstrap类加载器是JVM的一部分,负责加载JDK的核心类库,如rt.jar,这...
Java类加载器和类加载机制实例分析 Java类加载器和类加载机制...通过本文,我们了解了Java类加载器和类加载机制的原理、实现方法及相关操作技巧,为我们在实际开发中使用Java类加载器和类加载机制提供了有价值的参考。
### Java虚拟机类装载的原理及实现 #### 引言 Java虚拟机(JVM)作为执行Java程序的核心,承担着解释执行字节码的重要任务。在这个过程中,类的装载是一个关键步骤,它确保了Java程序能够正确无误地运行。类装载...
2. **类加载器及类加载器的委托机制**:JVM中有三种内置的类加载器,分别是启动类加载器、扩展类加载器和应用类加载器。此外,还可以自定义类加载器。类加载器之间遵循委托机制,即下级类加载器先请求上级类加载器...
1. 类装载器:负责加载类文件,将字节码转换为运行时的数据结构。它遵循双亲委派模型,确保类的唯一性。 2. 运行数据区:分为堆内存和栈内存。堆内存是所有对象的存储区域,而栈内存主要存储方法的局部变量和方法...
"浅谈JAVA虚拟机JVM及工作原理" Java虚拟机(JVM)是Java语言的 runtime 环境,它提供了一个平台独立的环境,使得Java程序可以跨平台运行。JVM 的主要组件包括虚拟机栈、堆、方法区、程序计数器、本地方法栈等。 1...
1. Bootstrap类加载器:加载JVM启动所需及标准扩展类。 2. System类加载器:加载Tomcat自身启动类,如bootstrap.jar。 3. Common类加载器:加载Tomcat和应用共用的类库,如servlet-api.jar。 4. Webapp类加载器:每...
在Java和Android系统中,类加载器负责查找、加载和初始化类。通过自定义类加载器,我们可以实现动态加载和替换修复后的类,从而达到热修复的效果。 1. **Android 类加载机制**: - 类加载过程包括加载(Loading)...
2. JVM加载类对象:JVM通过类加载器加载`.class`文件,解析元数据生成`Class`对象。 3. JVM对反射的支持:JVM提供了相应的API来支持反射操作,如`invoke`指令用于调用方法,`getfield`和`putfield`用于访问字段。 ...
Java有三种内置类加载器:启动类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用程序类加载器(Application ClassLoader)。用户还可以自定义类加载器。 2. **双亲委派模型**:类...