java反射机制剖析— Class Loader

反射机制总结为Java提供了运行时加载类的能力,也就是动态性。Class是信息提供者,Class Loader是加载工具,二者都是反射机制最基础的部分。那么所谓的反射就是解除耦合,方式就是通过Class取得未知类的信息,而后实例化。当然Class Loader的所做的工作是隐藏的,是Class对象去调用的。所以无需显示的自己调用。


简介

    ClassLoader是负责加载类的对象,作用是根据Jvm请求提供的类信息,将请求的类加载的内存中或者说加载到Jvm中。另外,每一个类的Class对象(注意Class是类类型)都持有一个对应的ClassLoader的引用。可以通过Class对象的getClassLoader()方法得到。类和它的ClassLoader是对应的,所以类只能通过它对应的ClassLoader加载。
    注意数组类的 Class 对象不是由类加载器创建的,而是由 Java 运行时根据需要自动创建。数组类的类加载器由 Class.getClassLoader() 返回,该加载器与其元素类型的类加载器是相同的;如果该元素类型是基本类型,则该数组类没有类加载器。

分类

    JVM在运行时会产生三个ClassLoader,Bootstrap ClassLoader、Extension ClassLoader和App ClassLoader。
    Bootstrap ClassLoader:是用C++编写的,是JVM的内置加载器,它的名字是null。它用来加载核心类库,即在lib下的类库。做个实验,首先,String类肯定是java的核心类,那我们就以它为例来看看:    
[java]  view plain  copy
  1. public static void main(String[] args){  
  2.         String a="x";  
  3.         System.out.println(a.getClass().getClassLoader());  
  4.     }  
            我们通过代码来获得String加载对应的ClassLoader的名字输出的结果为NULL。
    Extension ClassLoader:加载lib/ext下的类库。
    App ClassLoader:加载Classpath里的类库。

层次关系

    之前我们说过,每一个Class对象都会持有一个对应的ClassLoader的引用。每一个ClassLoader对象也会持有一个Parent ClassLoader的引用。这里需要特别注意的是:这里所指的的Parent ClassLoader不是我们熟悉的继承关系,不是父类!!首先,我们要知道这里说的是ClassLoader对象,也就是说这的Parent ClassLoader其实是一个对象的引用。下面看一张图,了解一下ClassLoader对象之间的层次关系:
           


       我们这里可以在做一个实验,来体会一下这个层次关系。代码如下:
         
[java]  view plain  copy
  1. public static void main(String[] args){       
  2.         ClassLoader c =TestClassLoader.class.getClassLoader();  
  3.         do {  
  4.             System.out.println(c.getClass().getName());  
  5.             c=c.getParent();  
  6.         }while(c!=null);          
  7.     }  
  8. }  
输出的结果为:
sun.misc.Launcher$AppClassLoader
sun.misc.Launcher$ExtClassLoader

双亲加载机制

    层次关系中我们了解到了很重要的一点:加载器对象之间的引用关系。被引用的对象称之为引用对象的父加载器,可以通过getParent()方法得到。那么双亲加载机制就是基于这种引用的层次关系。即:当一个ClassLoader接到请求时,它不是直接加载对应的类,而是询问它引用的ClassLoader是否能够加载,而这个父ClassLoader则会询问自己的引用的ClassLoader是否加载了该类。只有当所有的父ClassLoader都没有加载该类时,这个最初的ClassLoader才自己去加载申请的类。
    很绕啊,文字说不清楚还是上图吧!


    双亲加载机制可以一定程度上保证安全性,因为只要顶层ClassLoader能加载的东西就一定不会让下层的ClassLoader有机会加载。也就保证了有些自定义的带有破坏性的类不会被加载到Jvm核心中。
    结语:ClassLoader相对难理解的地方一个是,对象将的层次关系和父加载器。另一个是双亲加载机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值