黑马程序员--------类加载器ClassLoader(二)

                      ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

类加载器

类加载器:

-java虚拟机自带的类加载器

   -根类加载器(BootStrap) c++ java代码中无法获得

   -扩展类加载器(Extension) java

   -系统类加载器 应用加载器(Ssystem)   java

-用户自定义的类加载器

 java.lang.ClassLaoader的子类

 用户可以定制类的加载方式 要继承Classloader类

父子加载器并非继承关系,也就是说子加载器不一定是继承了父加载器。

 

类加载器的父亲委托机制(Parent Delegation).

类加载器用来把类加载到java虚拟机中。从jdk1.2开始,类加载过程采用父亲委托机制,这种机制能更好的保证java平台的安全。再次委托机制中,除了java虚拟机再带的跟类加载器外,其余的类加载器都有且只有一个父类加载器。当java程序请求加载器loader加载Sample类时,

loader首先委托自己的父类加载器去加载Sample类,若父加载器能加载,则由父加载器完成加载任务,否则才由加载器loader本身加载Sample类。

在父亲委托机制中,各个加载器按照父子关系形成了树形结构,除了跟类加载器以外,其余的类加载器都有且只有一个父加载器。

JVM自带的加载器之间的关系

       

类加载器的父亲委托机制:

    

Class sampleClass = loader2.loadClass(“Sample”);

Loader2首先从自己的命名空间中查找Sample类是否已经被加载,如果已经加载,就直接返回代表Sample类的Class对象的引用。

如果Sample类还没有被加载,loader2首先请求loader1代为加载loader1再请求系统类加载器代为加载,系统类加载器再请求扩展类加载器代为加载,扩展类加载器再请求根类加载器代为加载。若跟类加载器和扩展加载器都不能加载,则系统类加载器加载,若能加载成功,则将Sample类所对应的Class对象的引用返回给loader1,loader1再讲引用返回给loader2,从而成功的Sample类加载进虚拟机。若系统类加载器不能加载Sample类则loader1尝试加载Sample类若loader2也不能成功加载,则loader2尝试加载。若所有的父加载器以及loader2本身都不能加载,则抛出ClassNotFountException异常。

 

若有一个类加载器能成功加载Sample类那么这个类加载器被成为定义类加载器,所有能成功返回Class对象的引用的类加载(包括定义类加载器)都被成为初始类加载器

 

假设loader1实际加载了Sample类,则loader1为Sample类的定义类加载器,loader2和loader1都是Sample类的初始类加载器。

 

当生成一个自定义的类加载器实例时,如果没有指定它的父加载器,那么系统类加载器就将成为该类加载器的父加载器。

 

父亲委托机制的优点是能够提高软件系统的安全性。因为在此机制下,用户自定义的类加载器不可能加载应该由父加载器加载的可靠类,从而防止不可靠甚至恶意代码代替由父加载器加载的可靠代码。例如:java.lang.Object类总是由跟加载器加载,其他任何用户自定义的类加载器都不可能加载含有恶意代码的java.lang.Object类

 

每个类加载器都有自己的命名空间。命名空间由该加载器及所有父加载器所加载的类组成。在同一个命名空间中,不会出现类的完整名字(包括类的包名)相同的两个类;再不同的命名空间中,有可能会出现类的完整名字(包括类的包名)相同的两个类。

 

由同一类加载器加载的属于相同包得类组成了运行时包。觉得链各个类是不是属于同一个运行时包,不仅要看他们的包名是否相同,还要看定义类加载器是否相同。

是由属于同一运行时包得类才能互相访问包课件(即默认访问级别)的类和类成员。这样的限制能避免用户自定义的类冒充核心类库的类,去访问核心类库的包可见成员。

假设用户自己定义一个类java.lang.Spy,并由用户自定义的类加载器加载,由于java.lang.Spy和核心类库java.lang.*由不同的加载器加载,他们属于不同的运行时包,所以

java.lang.Spy不能访问核心类库java.lang包中的包课件成员。

 

创建用户自定义的类加载器,只要扩展java.lang.ClassLoader类。然后覆盖它的findClass(String name)方法即可,该方法根据参数指定类的名字,返回对应的Class对象的引用。

 

不同类加载器的命名空间的关系

同一个命名空间内的类是互相可见的。

字加载器的命名空间包含所有父加载器的命名空间。因此由子类加载器加载的类能看见父加载器加载的类。例如系统类加载器加载的类能看见根类加载器加载的类。

由父加载器加载的类不能看见子类加载器加载的类

如果两个加载器之间没有直接或间接的父子关系那么他们各自加载的类相互不可见。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值