类加载器

  类加载器用来把类加载到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

JVM中类加载器的父委托机制的更多相关文章

  1. Java虚拟机JVM学习05 类加载器的父委托机制

    Java虚拟机JVM学习05 类加载器的父委托机制 类加载器 类加载器用来把类加载到Java虚拟机中. 类加载器的类型 有两种类型的类加载器: 1.JVM自带的加载器: 根类加载器(Bootstrap ...

  2. JVM 类加载器的双亲委托机制

    1.类加载器的层次结构 在双亲委托机制中,各个加载器按照父子关系形成了树形结构(逻辑意义),除了根加载器之外,其余的类加载器都有且只有一个父加载器. public class MyTest13 { p ...

  3. java类加载器学习2——自定义类加载器和父类委托机制带来的问题

    一.自定义类加载器的一般步骤 Java的类加载器自从JDK1.2开始便引入了一条机制叫做父类委托机制.一个类需要被加载的时候,JVM先会调用他的父类加载器进行加载,父类调用父类的父类,一直到顶级类加载 ...

  4. JAVA类加载器一 父类委托机制

    感谢原文作者:不将就! 原文链接:https://www.cnblogs.com/byron0918/p/5770653.html 类加载器负责将.class文件加载到内存中,并为之生成对应的Clas ...

  5. Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论

    Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论 创建用户自定义的类加载器 要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的f ...

  6. 一、JVM之类加载器

    一.什么是JVM 先来看下百度百科的解释: JVM 是 Java Virtual Machine(Java 虚拟机)的缩写,JVM 是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计 ...

  7. 我把JVM的类加载器整理了一下

    前言 ​ 之前去面试的时候面试官问了我关于关于JVM性能调优的问题,由于自己之前公司的项目里自己没有接触到JVM性能调优的相关问题(感觉这些都是公司架构师考虑的问题),所有面试官问的时候自己一脸懵逼, ...

  8. 1.1 jvm核心类加载器--jdk源码剖析

    目录 前提: 运行环境 1. 类加载的过程 1.1 类加载器初始化的过程 1.2 类加载的过程 1.3 类的懒加载 2. jvm核心类加载器 3. 双亲委派机制 4. 自定义类加载器 5. tomca ...

  9. 深入JVM系列(三)之类加载、类加载器、双亲委派机制与常见问题

    一.概述   定义:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型.类加载和连接的过程都是在运行期间完成的. 二. 类的 ...

随机推荐

  1. [Luogu2014]选课(树形dp)

    [Luogu2014]选课 题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习.现在有N门功课 ...

  2. git 使用远程分支覆盖本地分支(重置本地分支)

    1 丢弃本地变更 重置为远端分支内容 git reset --hard origin/branchName 如 git reset --hard origin/F_AssetItem

  3. Integer类的缓存机制

    一.Integer类的缓存机制 我们查看Integer的源码,就会发现里面有个静态内部类. public static Integer valueOf(int i) { assert IntegerC ...

  4. R语言里面的循环变量

    for (i in 1:10) { print("Hello world") } 以上这条命令执行完之后,变量i会被保存下来!并且,i的值将是10. 程序中有多处循环的时候要非常注 ...

  5. php上传文件的原理

    文件上传原理 将客户端的文件上传到服务器,再将服务器的临时文件上传到指定目录 客户端配置 提交表单 表单的发送方式为post 添加enctype="multipart/form-data&q ...

  6. 四-1、Cadence Allegro推荐操作方式和视图命令

    第四章:实用命令详解 1.Cadence Allegro推荐操作方式: 激活命令 选择操作对象的属性 设置相关的命令参数 单击对应的对象 结束命令 2.视图命令:

  7. yum源更换

    折腾了半天,怀疑自己能力 的时候,发现原来不是我的错.树莓派换源国内的aliyun,163都不能用,最好找到这个 # CentOS-Base.repo # # The mirror system us ...

  8. WIN7自带端口转发渗透小技巧

    目标是WIN7 X64,且开启了防火墙,想要用他的机器去访问别的机器,又不想登陆他的系统,常规办法一般是上传一个htran,然后进行转发,但是对方有杀软,有被杀的可能性,所以我用另外一种办法达到我的目 ...

  9. Photon学习(一)——Photon Networking Free网络组件学习

    一般前端untiy程序员都很想自己学会后端网络编程,这样一个人就可以把前后端都做了,做网络游戏可比单机游戏好玩多了,笔者我对喜欢的就是mmo多人对战游戏,一起组队打副本,一起体验多人对战的乐趣.从业以 ...

  10. 用三目运算,与if判断 函数调用 达到相同判定作用

    三目运算符:     操作数1 ? 操作数2 : 操作数3   (操作数1位bool类型,操作数2和操作数3为两个相同的任何类型) 返回结果:如果操作数1判定结果为真,则将操作数2作为返回结果如果操作 ...