`

JVM中类加载器的父委托机制

阅读更多

类加载器

  类加载器用来把类加载到Java虚拟机中。

 

类加载器的类型

  有两种类型的类加载器:

  1.JVM自带的加载器:

    根类加载器(Bootstrap)

    扩展类加载器(Extension)

    系统类加载器(System)

  2.用户自定义的类加载器:

    java.lang.ClassLoader的子类,用户可以定制类的加载方式。

 

JVM自带的加载器

  Java虚拟机自带了以下几种加载器。

  1.根(Bootstrap)类加载器:

  该加载器没有父加载器

  它负责加载虚拟机的核心类库,如java.lang.*等。

  根类加载器从系统属性sun.boot.class.path所指定的目录中加载类库。

  根类加载器的实现依赖于底层操作系统,属于虚拟机的实现的一部分,它并没有继承java.lang.ClassLoader类,它是用C++写的。

 

  2.扩展(Extension)类加载器:

  它的父加载器为根类加载器。

  它从java.ext.dirs系统属性所指定的目录中加载类库,或者从JDK的安装目录的jre\lib\ext子目录(扩展目录)下加载类库,如果把用户创建的JAR文件放在这个目录下,也会自动由扩展类加载器加载。

  扩展类加载器是纯Java类,是java.lang.ClassLoader类的子类。

 

  3.系统(System)类加载器:

  也称为应用类加载器,它的父加载器为扩展类加载器

  它从环境变量classpath或者系统属性java.class.path所指定的目录中加载类,它是用户自定义的类加载器的默认父加载器

  系统类加载器是纯Java类,是java.lang.ClassLoader类的子类。

 

  注意:这里的父加载器概念并不是指类的继承关系,子加载器不一定继承了父加载器(其实是组合的关系)。

 

用户自定义类加载器

  除了以上虚拟机自带的类加载器以外,用户还可以定制自己的类加载器(User-defined Class Loader)。

  Java提供了抽象类java.lang.ClassLoader,所有用户自定义的类加载器都应该继承ClassLoader类。

 

类加载的父委托机制

  从JDK 1.2版本开始,类的加载过程采用父亲委托机制,这种机制能更好地保证Java平台的安全。

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

 

  当Java程序请求加载器loader1加载Sample类时,loader1首先委托自己的父加载器去加载Sample类,若父加载器能加载,则由父加载器完成加载任务,否则才由loader1本身加载Sample类。

 

  说明具体过程的一个例子:

 

 

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

  如果Sample类还没有被加载,loader2首先请求loader1代为加载,loader1再请求系统类加载器代为加载,系统类加载器再请求扩展类加载器代为加载,扩展类加载器再请求根类加载器代为加载。

  若根类加载器和扩展类加载器都不能加载,则系统类加载器尝试加载,若能加载成功,则将Sample类所对应的Class对象的引用返回给loader1,loader1再返回给loader2,从而成功将Sample类加载进虚拟机。

  若系统加载器不能加载Sample类,则loader1尝试加载Sample类,若loader1也不能成功加载,则loader2尝试加载。

  若所有的父加载器及loader2本身都不能加载,则抛出ClassNotFoundException异常。

  总结下来就是:

  每个加载器都优先尝试用父类加载,若父类不能加载则自己尝试加载;若成功则返回Class对象给子类,若失败则告诉子类让子类自己加载。所有都失败则抛出异常。

 

定义类加载器和初始类加载器

  若有一个类加载器能成功加载Sample类,那么这个类加载器被称为定义类加载器

  所有能成功返回Class对象的引用的类加载器(包括定义类加载器,即包括定义类加载器和它下面的所有子加载器)都被称为初始类加载器

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

 

父子关系

  需要指出的是,加载器之间的父子关系实际上指的是加载器对象之间的包装关系,而不是类之间的继承关系。

  一对父子加载器可能是同一个加载器类的两个实例,也可能不是。

  在子加载器对象中包装了一个父加载器对象。

  例如loader1和loader2都是MyClassLoader类的实例,并且loader2包装了loader1,loader1是loader2的父加载器。

  当生成一个自定义的类加载器实例时,如果没有指定它的父加载器(ClassLoader构造方法无参数),那么系统类加载器就将成为该类加载器的父加载器。

 

父委托机制优点

  父亲委托机制的优点是能够提高软件系统的安全性

  因为在此机制下,用户自定义的类加载器不可能加载应该由父加载器加载的可靠类,从而防止不可靠甚至恶意的代码代替由父加载器加载的可靠代码。

  例如,java.lang.Object类总是由根类加载器加载,其他任何用户自定义的类加载器都不可能加载含有恶意代码的java.lang.Object类。

 

命名空间

  每个类加载器都有自己的命名空间,命名空间由该加载器及所有父加载器所加载的类组成。

  在同一个命名空间中,不会出现类的完整名字(包括类的包名)相同的两个类。

  在不同的命名空间中,有可能会出现类的完整名字(包括类的包名)相同的两个类。

运行时包

  由同一类加载器加载的属于相同包的类组成了运行时包

  决定两个类是不是属于同一个运行时包,不仅要看它们的包名是否相同,还要看定义类加载器是否相同。

  只有属于同一运行时包的类才能互相访问包可见(即默认访问级别)的类和类成员。

  这样的限制能避免用户自定义的类冒充核心类库的类,去访问核心类库的包可见成员。

  假设用户自己定义了一个类java.lang.Spy,并由用户自定义的类加载器加载,由于java.lang.Spy和核心类库java.lang.*由不同的类加载器加载,它们属于不同的运行时包,所以java.lang.Spy不能访问核心类库java.lang包中的包可见成员。

 

http://uule.iteye.com/blog/2114378

分享到:
评论

相关推荐

    深入java虚拟机(六)——类加载的父亲委托机制1

    1. 当需要加载一个类时,首先由当前类加载器询问其父类加载器是否能加载。 2. 如果父类加载器能加载,就交给父类加载,否则返回“找不到类”的异常信息。 3. 若父类加载器无法加载,当前类加载器才尝试从指定的源中...

    深入Java虚拟机_002_深入详解JVM之类加载器深度剖析、根、扩展及系统类加载器

    在Java开发中,理解JVM的类加载机制对于优化性能、解决类冲突问题、实现自定义类加载器等都有重要意义。例如,通过自定义类加载器可以实现动态加载类、隔离不同版本的库,或者实现热部署等高级功能。 总的来说,JVM...

    JVM实战-JVM类加载机制案例分析

    2. **类加载器及类加载器的委托机制**:JVM中有三种内置的类加载器,分别是启动类加载器、扩展类加载器和应用类加载器。此外,还可以自定义类加载器。类加载器之间遵循委托机制,即下级类加载器先请求上级类加载器...

    解析Java虚拟机中类的初始化及加载器的父委托机制共14页

    本文将深入探讨Java虚拟机中的类初始化以及加载器的父委托机制。 一、类的加载 类加载是JVM启动时或运行中根据需要动态加载类到内存中的过程。这个过程分为三个阶段:加载、链接和初始化。 1. 加载:JVM通过类...

    JVM:类加载器子系统.pdf

    当一个类加载器需要加载一个类时,它首先将这个加载任务委托给父类加载器,这样一层一层向上传递,直到最顶层的引导类加载器。如果父类加载器无法完成加载任务(例如因为找不到对应的类文件),子类加载器才会尝试...

    JVM、Tomcat、OSGI等类加载器整理文档

    每个类加载器都可以通过`getParent()`方法获取其父类加载器。这种关系不是继承关系,而是基于委托的设计模式。类加载器组织成树形结构,引导类加载器作为根节点。 - **启动类加载器**:负责加载Java核心库,如rt....

    JAVA-JVM-01类加载机制

    在`loadClass()`方法中,实现了双亲委派机制,先尝试父加载器,然后是当前类加载器的`findClass()`方法。`findClass()`方法默认抛出异常,我们需要重写它,以便读取并加载自定义路径下的类文件。 总结,Java的类...

    从JDK源码级别剖析JVM类加载机制

    类加载器按照双亲委派模型工作,即子类加载器优先尝试委托父类加载器加载,只有当父类加载器无法加载时,子类加载器才会尝试自己加载。 2. **链接**: 链接阶段分为验证、准备和解析三个子步骤。 - **验证**:...

    JVM加载class文件的原理机制

    JVM加载class文件的原理机制是Java中的核心机制之一,由于Java中的所有类必须被装载到JVM中才能运行,这个装载工作是由JVM中的类装载器完成的。类装载器所做的工作实质是把类文件从硬盘读取到内存中。 类加载机制 ...

    类加载器(java)

    类加载器的工作机制遵循“双亲委派模型”:当一个类加载器接收到加载类的请求时,它首先会委托父加载器去尝试加载,只有在父加载器无法加载的情况下,子加载器才会尝试自己去加载。这种设计可以防止类的重复加载,并...

    Java类加载器原理

    3. 加载器委托加载机制: 类加载器遵循“双亲委派模型”(Delegation Model)。当一个类加载器接收到加载类的请求时,它首先会委托其父类加载器去尝试加载,如果父类加载器无法加载,再由当前加载器尝试。这个过程...

    java类加载器和核心机制.pdf

    在类加载器的层次结构中,还有一个重要的机制是双亲委托机制。这是一种代理模式,使得一个类加载器在加载类时会先委托给父加载器进行尝试,只有当父加载器无法完成这个加载任务时,子加载器才会尝试自己去加载这个类...

    【JVM】类加载器与双亲委派模型

    双亲委派机制在`ClassLoader`的`loadClass()`方法中体现,方法内部首先检查类是否已经加载,然后尝试将加载请求委托给父加载器,最后如果父加载器无法加载,才由当前加载器自行加载。通过这种方式,保证了像`java....

    Java类加载原理解析

    当一个类加载器收到加载类的请求时,它首先会将请求委托给其父类加载器,直到达到顶层的启动类加载器。只有当父类加载器无法找到指定类时,当前类加载器才会尝试自己加载。这种机制避免了类的重复加载,并确保了核心...

    JVM加载class文件的原理机制.pdf

    JVM加载class文件的原理机制是Java虚拟机中一个非常重要的组件,负责将class文件加载到内存中,以便Java程序的执行。下面是JVM加载class文件的原理机制的详细介绍: 类加载的原理 在Java中,所有的类都必须被加载...

    jvm字节码自动加载

    当一个类加载请求到来时,除非已经加载过该类,否则JVM会委托父类加载器去尝试加载,只有当父类加载器无法加载时,才会尝试用自己的加载器进行加载。这样可以防止不同加载器加载相同的类造成的问题,保持类加载的...

    Java类加载器机制与模型.pdf

    Java类加载器采用了**双亲委派模型(Parent Delegation Model)**,这意味着当一个类加载器收到加载类的请求时,它首先会委托其父类加载器去尝试加载,只有当父类加载器无法加载时,当前类加载器才会尝试自己加载。...

    深入研究Java类加载机制 深入研究Java类加载机制

    Java中的类加载器遵循一个原则叫做“父母委托模型”,即当一个类加载器收到类加载请求时,首先将加载任务委托给父类加载器,只有当父类加载器无法完成加载时才会尝试自己加载。 这种设计模式的好处在于避免了类的...

    自定义类加载器

    当一个类加载器接收到加载类的请求时,它首先会委托其父加载器尝试加载,只有当父加载器无法找到对应的类时,才会尝试自己加载。这种设计确保了类的唯一性,防止类的重复加载和安全问题。 ### 自定义类加载器的创建...

Global site tag (gtag.js) - Google Analytics