ClassLoader()

来源:互联网 发布:mysql skip limit 编辑:程序博客网 时间:2024/06/05 10:48

ClassLoader
主要对类的请求提供服务,当JVM需要某类时,它根据名称向ClassLoader要求这个类,然后由ClassLoader返回这个类的class对象

  • 1.1 几个相关概念
    ClassLoader负责载入系统的所有Resources(Class,文件,来自网络的字节流等),通过ClassLoader从而将资源载入JVM
    每个class都有一个reference,指向自己的ClassLoader。Class.getClassLoader()
    array的ClassLoader就是其元素的ClassLoader,若是基本数据类型,则这个array没有ClassLoader
  • 装载类的过程
 Test test = new Test(); test.class.getClassLoader();

Java是面向对象语言,面向对象的语言的宗旨就是万事万物皆对象,那么类也是一个对象,类里面的属性和方法也是对象。java里面的所有的类都是Class类的对象,这个test.class是获得这个类相对于Class类的对象。后面的方法getClassLoader()是获得这个类对象的加载器。
Class类也提供了许多方法来获取类的信息. 要知道,类的装载器分为 “启动类装载器 “, “用户定义装载器 “.它不止一种 ,Class类需要保存这些信息. getClassLoader()是用来获取这个信息的
装载类的过程非常简单:查找类所在位置,并将找到的Java类的字节码装入内存,生成对应的Class对象。Java的类装载器专门用来实现这样的过程,JVM并不止有一个类装载器,事实上,如果你愿意的话,你可以让JVM拥有无数个类装载器,除了用于测试,并没有什么用.

  • 类装载器
    类装载器自身也是一个类,它也需要被装载到内存中来,由Bootstrap ClassLoader完成.java的运行环境所需要的所有类库,都由Bootstrap ClassLoader来装载,而它本身是C++写的程序,可以独立运行,可以说是JVM的运行起点。在Bootstrap完成它的任务后,会生成一个AppClassLoader(实际上之前系统还会使用扩展类装载器ExtClassLoader,它用于装载Java运行环境扩展包中的类),这个类装载器才是我们经常使用的,可以调用ClassLoader.getSystemClassLoader() 来获得,我们假定程序中没有使用类装载器相关操作设定或者自定义新的类装载器,那么我们编写的所有java类通通会由AppClassLoader来装载.
    AppClassLoader查找类的区域是耳熟能详的Classpath,我们按照其类查找范围给它取名为类路径类装载器。还是先前假定的情况,当Java中出现新的类,AppClassLoader首先在类传递给它的父类类装载器,也就是Extion ClassLoader,询问它是否能够装载该类,如果能,那AppClassLoader就不再加载,同样Extion ClassLoader在装载时,也会先问问它的父类装载器。我们可以看出类装载器实际上是一个树状的结构图,每个类装载器有自己的父亲,类装载器在装载类时,总是先让自己的父类装载器装载,如果父类装载器无法装载该类时,自己就会动手装载,如果它也装载不了,则抛出异常:Exception,class not found。有必要提一句,当由直接使用 类路径装载器 装载类失败抛出的是NoClassDefFoundException异常。如果使用自定义的类装载器loadClass方法或者ClassLoader的findSystemClass方法装载类,如果你不去刻意改变,那么抛出的是ClassNotFoundException。
    jdk中,如果一个类是通过bootstrap 载入的,那我们通过这个类去获得classloader的话,有些jdk的实现是会返回一个null的,比如说用 new Object().getClass().getClassLoader()的话,会返回一个null,这样的话上面的代码就会出现NullPointer异常.所以保险起见我们最好还是使用我们自己写的类来获取classloader(”this.getClass().getClassLoader()“),这样一来就不会有问题。
原创粉丝点击