在上一篇博文中,我们知道了如何获得二进制的字节流,并根据获得的字节流去装载一个类。同时也了解到类加载器的存在,每个加载器对应着不同的加载目录,相互配合着,从而使整个加载过程稳定而安全。 
  那么他们是如何配合的呢?如果我自己写一个类,名字叫做String可以吗? 
  首先我们来看一张图: 
 
  图中除了最底下的那个加载器是我们没有讲到的,其余的都有说到过。其实底下那个就是我们自己实现的类加载器,用于自定义加载class。 
  在虚拟机中,类的加载采用的是双亲委派模型。该模型需要有一个前提条件:除了顶层的类加载器之外,其余的类加载器都应该有自己的父加载器,这里的父加载器指的不是继承,而是组合,即App ClassLoader加载器里面应该要有Extension ClassLoader加载器的引用(为什么用组合而不用继承,大家可以想想其中的利弊)。 
  基本工作过程就是:当一个类加载器收到了类加载的请求,他首先不会尝试自己去加载这个类,而是将这次的请求委派给自己的父类加载器去加载。如果父类加载器依然不能加载,则继续用父加载器的父加载器去加载(有点拗口)。层层如此,如果都不能加载,则最终的结果就是到达顶层——启动类加载器Bootstrap ClassLoader。每一层的类加载器都会根据请求所要加载的类去自己应该加载的目录中搜索有没有对应的类和查看该类是否已经被加载。如果有,那么该层加载器加载并返回,如果到达了启动类加载器后还是不能加载,那么就由最初接收到类加载请求的那个类加载器进行加载。 
  因此,可以从图或者刚刚的工作过程看出:要加载类就先要检查是否已经加载了和是不是自己应该要加载的类,这个过程是自底向上的。那么如果上层反馈说该类没有被加载,并且我和我的父加载器都不能加载,你自己加载吧,这个过程是从上往下的。 
我们来看看虚拟机是怎么实现该双亲模型的: 
 
  通过findLoadedClass判断是否已经加载了,如果加载了,则返回这个类,否则就判断有没有父加载器,如果有就交给父加载器加载。如果祖先都不能加载,就交给当前的加载器加载。 
  双亲委派模式很好地解决了各个类加载器的基础类统一问题,越基础的类由越上层的类加载器进行加载。分工与责任明确,解决部分安全问题,如自定义的加载器不能加载根加载器应该加载的类,很好的避免了恶意写入基础类。 
  例子:我们常用的String类位于rt.jar下。由上一博文的知识可以知道,该jar包是由Bootstrap ClassLoader进行加载的,那么如果我们自己写一个类也叫作String,那么当加载的时候,就会先检查出该类已经被加载了,所以不再允许其他的加载器重新加载,因此我们自己写的String类也就不能用了,所以我们不能自己写一个叫做String的类。

JVM(16)之 双亲委派模型的更多相关文章

  1. 类文件的结构、JVM 的类加载过程、类加载机制、类加载器、双亲委派模型

    一.类文件的结构 我们都知道,各种不同平台的虚拟机,都支持 "字节码 Byte Code" 这种程序存储格式,这构成了 Java 平台无关性的基石.甚至现在平台无关性也开始演变出 ...

  2. 【深入理解JVM】类加载器与双亲委派模型

    原文链接:http://blog.csdn.net/u011080472/article/details/51332866,http://www.cnblogs.com/lanxuezaipiao/p ...

  3. JVM总括四-类加载过程、双亲委派模型、对象实例化过程

    JVM总括四-类加载过程.双亲委派模型.对象实例化过程 目录:JVM总括:目录 一. 类加载过程 类加载过程就是将.class文件转化为Class对象,类实例化的过程,(User user = new ...

  4. JVM类加载机制详解(二)类加载器与双亲委派模型

    在上一篇JVM类加载机制详解(一)JVM类加载过程中说到,类加载机制的第一个阶段加载做的工作有: 1.通过一个类的全限定名(包名与类名)来获取定义此类的二进制字节流(Class文件).而获取的方式,可 ...

  5. 【深入理解JVM】:类加载器与双亲委派模型

    类加载器 加载类的开放性 类加载器(ClassLoader)是Java语言的一项创新,也是Java流行的一个重要原因.在类加载的第一阶段“加载”过程中,需要通过一个类的全限定名来获取定义此类的二进制字 ...

  6. jvm双亲委派模型

    其实,双亲委派模型并不复杂.自定义类加载器也不难!随便从网上搜一下就能搜出一大把结果,然后copy一下就能用.但是,如果每次想自定义类加载器就必须搜一遍别人的文章,然后复制,这样显然不行.可是自定义类 ...

  7. JVM类加载过程与双亲委派模型

    类加载过程 类加载过程为JVM将类描述数据从.class文件中加载到内存,并对数据进行解析和初始化,最终形成被JVM直接使用的Java类型.包含: 加载:获取该类的二进制字节流,将字节流代表的静态存储 ...

  8. JVM的类加载过程以及双亲委派模型详解

    JVM的类加载过程以及双亲委派模型详解 这篇文章主要介绍了JVM的类加载过程以及双亲委派模型详解,类加载器就是根据指定全限定名称将 class 文件加载到 JVM 内存,然后再转化为 class 对象 ...

  9. JVM探究之 —— 类加载器-双亲委派模型

    虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类.实现这个动作的代码模块称为“类加载器 ...

随机推荐

  1. 使用Varnish加速Web

    通过配置Varnish缓存服务器,实现如下目标: - 使用Varnish加速后端Web服务 - 代理服务器可以将远程的Web服务器页面缓存在本地 - 远程Web服务器对客户端用户是透明的 - 利用缓存 ...

  2. docker安装es

    下载镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:6.8.1 创建容器并映射docker run -e ES_JAVA_OP ...

  3. 【LeetCode】按 tag 分类索引 (900题以下)

    链表:https://www.cnblogs.com/zhangwanying/p/9797184.html (共34题) 数组:https://www.cnblogs.com/zhangwanyin ...

  4. Spring的事物原理

    在Spring中把非功能性的事物管理代码以切面的形式进行管理,只需要声明事物即可启用事物管理. 本质:最终执行的还是java.sql.Connection的setAutoCommit(),commit ...

  5. 【串线篇】spring boot全面接管springMvc

    一.Spring MVC auto-configuration Spring Boot 自动配置好了SpringMVC 以下是SpringBoot对SpringMVC的默认配置:(WebMvcAutoC ...

  6. [POJ 1911] 棋盘

    问题描述 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次切割都只能沿着 ...

  7. @ContrllerAdvice全局异常

    @ControllerAdvice,是Spring3.2提供的新注解,它是一个Controller增强器,可对controller中被 @RequestMapping注解的方法加一些逻辑处理.最常用的 ...

  8. securityDemopom

    <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> &l ...

  9. Flask学习笔记02之配置文件

    1. Flask默认的配置 Flask实例中包含了它的配置信息 #实例化一个Flask对象 app = Flask(__name__) # 打印默认配置信息 print(app.config) 打印结 ...

  10. oracle中where子句和having子句中的区别

    1.where  不能放在GROUP BY 后面2.HAVING 是跟GROUP BY 连在一起用的,放在GROUP BY 后面,此时的作用相当于WHERE3.WHERE  后面的条件中不能有聚集函数 ...