作者: Peter V. Mikhalenko
2006-07-07 10:04:41
类加载器是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给出了可以运行的自定义类加载器示例。
总结
如果对类加载机制有很好的理解,则可以从ClassNotFound 或 ClassCastException错误调试工作中解脱出来。当软件在第三方软件服务器中工作时,因为app服务器经常使用私有而复杂的类加载器,此时对类加载机制的理解则非常重要。
Peter V. Mikhalenko是通过Sun认证的专家,他在 Deutsche Bank银行担任商业顾问。
分享到:
相关推荐
### Java虚拟机中ClassLoader概述与双亲委托机制详解 #### 一、ClassLoader概念与作用 在Java编程语言中,`ClassLoader`是一个非常重要的组件,它负责加载程序运行所需的类文件到Java虚拟机(JVM)中。`ClassLoader`...
在Java虚拟机(JVM)中,类加载器(ClassLoader)是至关重要的组成部分,它负责查找和加载类的字节码文件。理解ClassLoader的工作机制对于深入掌握Java应用程序的运行至关重要。这里我们将详细讨论ClassLoader的运行...
《深入理解ClassLoader工作机制》 Java虚拟机(JVM)中的ClassLoader是负责加载类到内存中的核心组件。它不仅承担着将字节码转换为可执行对象的重任,还参与了类生命周期的各个阶段,包括加载、验证、准备、解析、...
在Java中,Classloader是加载类的关键组件,它负责查找、加载和初始化字节码文件。自定义Classloader允许开发者根据特定需求定制类的加载逻辑,例如加密类文件、隔离不同版本的库或者动态加载代码。本文将深入探讨...
在Java编程语言中,ClassLoader是一个至关重要的组成部分,它负责加载类到JVM(Java虚拟机)中,使得程序能够执行。本示例"ClassLoader小例子"将深入探讨这个概念,并通过一个具体的程序来演示其工作原理。下面我们...
Java ClassLoader是Java运行时系统的关键但经常被忽视的组件,负责在运行时查找和加载类文件。通过创建自定义ClassLoader,你可以定制JVM,使类文件的引入方式完全重新定义,这提供了很多实用和有趣的可能。这篇教程...
Java ClassLoader机制是Java虚拟机(JVM)中一个至关重要的组成部分,它的主要任务是将类的.class文件加载到JVM中,使得程序能够运行。ClassLoader不仅负责类的加载,还涉及类的验证、初始化等一系列过程。理解...
在Java编程语言中,`ClassLoader`是一个至关重要的组件,它负责加载类到JVM(Java虚拟机)中。本文将深入探讨`ClassLoader`的工作原理、加密解密应用程序以及如何防止类被反编译。 首先,让我们理解`ClassLoader`的...
在Java编程语言中,ClassLoader是一个至关重要的组成部分,它负责加载类到JVM(Java虚拟机)中。理解ClassLoader的工作原理以及如何定制它,对于深入学习Java的运行机制和进行高级应用开发具有重要意义。本篇文章将...
在Java世界中,类加载器(ClassLoader)是关键的组件之一,它负责将类的字节码文件(.class)从文件系统或网络中加载到Java虚拟机(JVM)中,使得程序能够运行。本篇文章将深入探讨ClassLoader的关系网络以及如何...
《ClassLoader详解》 Java应用程序的运行离不开类的加载,而ClassLoader正是这个过程的关键角色。它负责将类的字节码加载到Java虚拟机(JVM)中并转换为可执行的Java对象。深入理解ClassLoader的工作原理对于优化...
Java ClassLoader机制是Java运行时环境中的核心组件之一,它负责加载类到JVM(Java虚拟机)中,使得程序能够执行。理解ClassLoader的工作原理对于优化应用性能、处理类加载问题以及实现自定义加载器至关重要。 首先...
在Java编程语言中,ClassLoader是核心组件之一,它负责加载类到JVM(Java虚拟机)中执行。本文将深入探讨ClassLoader的工作原理和类加载机制,帮助开发者理解这个至关重要的概念。 1. 类加载机制概述 Java的类加载...
在Java编程语言中,ClassLoader是一个至关重要的组成部分,它负责加载类到JVM(Java虚拟机)中执行。这篇测试主要探讨了ClassLoader的工作原理及其在实际应用中的使用。通过阅读给出的博文链接,我们可以深入理解...
### Java ClassLoader与ClassPath详解 #### 一、概述 在Java编程中,类加载机制是十分关键的一个环节。类加载器(`ClassLoader`)负责将编译后的`.class`文件加载到Java虚拟机(JVM)中执行,而类路径(`ClassPath...
Java的类加载器(ClassLoader)体系结构是JVM(Java虚拟机)中至关重要的一部分,它负责将类的字节码转换为运行时的类实例。本文将深入探讨启动类加载器、扩展类加载器、系统类加载器以及用户自定义类加载器,同时还...
破解java加密的ClassLoader.java,在classloader植入破解代码