每次创建一个 Java 类的实例时候,必须先将类加载到内存中。Java 虚拟机(JVM)使用classloader来加载类。如果需要的类找不到,会抛出java.lang.ClassNotFoundException 异常。
从 J2SE1.2 开始,JVM 使用了三种类加载器:bootstrap 类加载器、extension类加载器和 systen 类加载器。这三个加载器是父子关系,其中 bootstrap 类加载器在顶端,而 system 加载器在结构的最底层。
其中 bootstrap 类加载器用于引导 JVM,一旦调用 java.exe 程序,bootstrap类加载器就开始工作。因此,它必须使用本地代码实现,然后加载 JVM 需要的类到函数中。另外,它还负责加载所有的 Java 核心类,例如 java.lang 和 java.io包。另外bootstrap 类加载器还会查找核心类库如 rt.jar、i18n.jar 等,这些类库根据 JVM 和操作系统来查找。
extension 类加载器负责加载标准扩展目录下面的类。这样就可以使得编写程序变得简单,只需把 JAR 文件拷贝到扩展目录下面即可,类加载器会自动的在下面查找。不同的供应商提供的扩展类库是不同的,Sun 公司的 JVM 的标准扩展目录是/jdk/jre/lib/ext。
system 加载器是默认的加载器,它在环境变量 CLASSPATH 目录下面查找相应的类。
这样,JVM 使用哪个类加载器?答案在于委派模型(delegation model),这是出于安全原因。每次一类需要加载,system 类加载器首先调用。但是,它不会马上加载类。相反,它委派该任务给它的父类-extension 类加载器。extension类加载器也把任务委派给它的父类 bootstrap 类加载器。因此,bootstrap 类加载器总是首先加载类。如果 bootstrap 类加载器不能找到所需要的类的extension 类加载器会尝试加载类。如果扩展类加载器也失败,system 类加载器将 执 行 任 务 。 如 果 系 统 类 加 载 器 找 不 到 类 , 一 个java.lang.ClassNotFoundException 异常。为什么需要这样的往返模式?委派模型对于安全性是非常重要的。如你所知,可以使用安全管理器来限制访问某个目录。现在,恶意的意图有人能写出一类叫做 java.lang.Object,可用于访问任何在硬盘上的目录。因为 JVM 的信任 java.lang.Object 类,它不会关注这方面的活动。因此,如果自定义 java.lang.Object 被允许加载的安全管理器将很容易瘫痪。幸运的是,这将不会发生,因为委派模型会阻止这种情况的发生。
下面是它的工作原理。
当自定义 java.lang.Object 类在程序中被调用的时候,system 类加载器将该请求委派给 extension 类加载器,然后委派给 bootstrap 类加载器。这样 bootstrap类加载器先搜索的核心库,找到标准 java.lang.Object 并实例化它。这样,自定义java.lang.Object 类永远不会被加载关于在 Java 类加载机制的优势在于可以通过扩展
java.lang.ClassLoader 抽象类来扩展自己的类加载器。
自定义自己的类加载器原因包括以下内容
· 要制定类加载器的某些特定规则
· 缓存以前加载的类
· 事先加载类以预备使用
Java classloader和委派模型(delegation model)
最新推荐文章于 2024-11-26 15:47:15 发布