java classLoader

在流行的商业化编程语言中,Java 语言由于在 Java 虚拟机 (JVM) 上运行而显得与众不同。这意味着已编译的程序是一种特殊的、独立于平台的格式,并非依赖于它们所运行的机器。在很大程度上,这种格式不同于传统的可执行程序格式。

C C++ 编写的程序不同,Java 程序并不是一个可执行文件,而是由许多独立的类文件组成,每一个文件对应于一个 Java 类。

此外,这些类文件并非立即全部都装入内存,而是根据程序需要装入内存。ClassLoader JVM 中将类装入内存的那部分。

而且,Java ClassLoader 就是用 Java 语言编写的。这意味着创建您自己的 ClassLoader 非常容易,不必了解 JVM 的微小细节。

如果 JVM 已经有一个 ClassLoader,那么为什么还要编写另一个呢?问得好。缺省的 ClassLoader 只知道如何从本地文件系统装入类文件。不过这只适合于常规情况,即已全部编译完 Java 程序,并且计算机处于等待状态。

Java 语言最具新意的事就是 JVM 可以非常容易地从那些非本地硬盘或从网络上获取类。例如,浏览者可以使用定制的 ClassLoader Web 站点装入可执行内容。

ClassLoader 的基本目标是对类的请求提供服务。当 JVM 需要使用类时,它根据名称向 ClassLoader 请求这个类,然后 ClassLoader 试图返回一个表示这个类的 Class 对象。

通过覆盖对应于这个过程不同阶段的方法,可以创建定制的 ClassLoader

Java ClassLoader 的关键方法

方法 loadClass

 



ClassLoader.loadClass() 是 ClassLoader 的入口点。其特征如下:

Class loadClass( String name, boolean resolve );

name 参数指定了 JVM 需要的类的名称,该名称以包表示法表示,如 Foojava.lang.Object

resolve 参数告诉方法是否需要解析类。在准备执行类之前,应考虑类解析。并不总是需要解析。如果 JVM 只需要知道该类是否存在或找出该类的超类,那么就不需要解析。

方法 defineClass

 


defineClass 方法是 ClassLoader 的主要诀窍。该方法接受由原始字节组成的数组并把它转换成 Class 对象。原始数组包含如从文件系统或网络装入的数据。

defineClass 管理 JVM 的许多复杂、神秘和倚赖于实现的方面 -- 它把字节码分析成运行时数据结构、校验有效性等等。

方法 findSystemClass

 



findSystemClass 方法从本地文件系统装入文件。它在本地文件系统中寻找类文件,如果存在,就使用 defineClass 将原始字节转换成 Class 对象,以将该文件转换成类。当运行 Java 应用程序时,这是 JVM 正常装入类的缺省机制。

方法 resolveClass



正如前面所提到的,可以不完全地(不带解析)装入类,也可以完全地(带解析)装入类。当编写我们自己的 loadClass 时,可以调用 resolveClass,这取决于 loadClassresolve 参数的值。

方法 findLoadedClass

 



findLoadedClass 充当一个缓存:当请求 loadClass 装入类时,它调用该方法来查看 ClassLoader 是否已装入这个类,这样可以避免重新装入已存在类所造成的麻烦。应首先调用该方法。

组装



看一下如何组装所有方法。

我们的 loadClass 实现示例执行以下步骤

  • 调用 findLoadedClass 来查看是否存在已装入的类。

  • 如果没有,那么采用那种特殊的神奇方式来获取原始字节。

  • 如果已有原始字节,调用 defineClass 将它们转换成 Class 对象。

  • 如果没有原始字节,然后调用 findSystemClass 查看是否从本地文件系统获取类。

  • 如果 resolve 参数是 true,那么调用 resolveClass 解析 Class 对象。

  • 如果还没有类,返回 ClassNotFoundException

  • 否则,将类返回给调用程序。

//使用defineClass 将字节数组转换成Class对象

    MyClassLoade myClassLoader=new MyClassLoade();

     Class c = myClassLoader.defineClass("Person", b1);

        System.out.println(c.getName());

//MyClassLoade

public class MyClassLoade extends ClassLoader {

    public Class defineClass(String name, byte[] b) {

       return defineClass(name, b, 0, b.length);

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值