Java的设计初衷是主要面向嵌入式领域,对于自己定义的一些类,考虑使用依需求载入原则。即在程序使用到时才载入类,节省内存消耗,这时就可以通过类载入器来动态载入。

假设你平时仅仅是做web开发,那应该非常少会跟类载入器打交道,但假设你想深入学习tomcatserver的架构,它是不可缺少的。所谓类载入器。就是用于载入Java类到Java虚拟机中,它负责读取Java字节码。并转换成java.lang.Class类的一个实例。使字节代码.class文件得以执行。

一般类载入器负责依据一个指定的类找到相应的字节代码,然后依据这些代码定义成一个Java类。另外还负责载入资源。包含图像文件和配置文件。

类载入器在实际使用中给我们带来的优点是。它能够使Java类动态地载入到JVM并执行。就可以在程序执行时再载入类,提供了非常灵活的动态载入方式。

比如我们熟悉的Applet,从远程server下载字节码到client动态载入到JVM便能够执行。

在Java的庞大体系中,能够将系统分为三种类载入器,各自是:

①   启动类载入器(Bootstrap ClassLoader):载入对象是Java核心库。把一些关键的Java类载入进JVM,这个载入器使用原生代码(C/C++)实现的。并非继承java.lang.ClassLoader,它是全部其它类载入器的终于父载入器,负责载入<JAVA_HOME>/jre/lib文件夹下且被JVM指定的类库。事实上它属于JVM总体的一部分,JVM一启动就将这些指定的类载入到内存中,避免以后过多的I/O操作。提高系统的执行效率。

启动类载入器无法被Java程序直接使用。

②   扩展类载入器(Extension ClassLoader):载入的对象为Java的扩展库。即载入<JAVA_HOME>/jre/lib/ext文件夹里面的类。

这个类由上面的Bootstrap ClassLoader载入,但因为Bootstrap ClassLoader并不是用Java实现,已经脱离了Java体系,所以假设尝试调用扩展类载入器的getParent()方法获取父载入器会得到null,但它的父类载入器是Bootstrap ClassLoader。

Java中能够直接使用扩展类载入器。

③   应用程序类载入器(Application  ClassLoader):亦叫系统类载入器(System ClassLoader),它负责载入用户类路径(CLASSPATH)指定的类库。假设程序没有自定义类载入器。就默认使用应用程序类载入器。它也由Bootstrap ClassLoader载入。但它的父载入类被设置成了Extension ClassLoader。

假设要使用这个载入器,可通过ClassLoader.getSystemClassLoader()获取。

假如有一天你心血来潮也想自己写一个类载入器,那么你仅仅须要继承java.lang.ClassLoader类就可以。于是能够用以下的图2-4-1来清晰表示出各种类载入器的关系,Bootstrap ClassLoader是最根本的类载入器,其不存在父类载入器,Extension ClassLoader由Bootstrap ClassLoader载入。所以它的父类载入器是Bootstrap ClassLoader。Application ClassLoader也是由Bootstrap ClassLoader载入,但它的父载入器被指向了Extension
ClassLoader,而其它全部用户自己定义的类载入器都由Application ClassLoader载入。

由此能够看出越重要的类载入器就越早被JVM载入,这是考虑到安全性。由于先载入的类载入器会充当下一个类载入器的父载入器,在双亲委派模型机制下,就能确保安全性。

那么什么是双亲委派模型?比方爷爷、爸爸、你三代单传,你们家族都遗传懒惰基因,每当遇到事情都互相推脱,如今须要一个人去买一包盐,不然今晚的菜就有色无味了。而你第一个被托付去超市买,但因为你的懒惰。你向你爸爸撒了一顿娇,你爸爸受不了你仅仅能答应帮你去,在懒惰的驱使下,你爸爸最后找了一个借口说要赶工作。让你爷爷出去走动走动顺便买一包盐,就这样你爷爷仅仅能乖乖去超市买盐。

双亲委派模型就类似这种机制。类载入器载入类时首先托付给父类载入器载入。除非父类载入器不能载入才自己载入。

这样的模型要求除了顶层的启动类载入器外,其它的类载入器都要有自己的父类载入器。假如有一个类要载入进来。一个类载入器并不会立即尝试自己将其载入,而是委派到父类载入器。父类载入器收到后又尝试委派到其父类载入器,以此类推,直到委派到启动类载入器,这样一层一层往上委派。仅仅有当父类载入器反馈自己没法完毕这个载入时,子载入器才会尝试自己载入。通过这个机制。保证了Java应用所使用的都是同一个版本号的Java核心库的类。同一时候这个机制也保证了安全性,设想假设Application ClassLoader想要载入一个有破坏性的java.lang.System类,双亲委派模型会一层层向上委派,终于委派给Bootstrap
ClassLoader,而Bootstrap ClassLoader检查到缓存中已经有了这个类。并不会再载入这个有破坏性的System类。

另外,类载入器还拥有全盘负责机制,即当一个ClassLoader载入一个类时,这个类所依赖的、引用的其它全部类都由这个ClassLoader载入,除非在程序中显性地指定另外一个ClassLoader载入。

图2-4-1 类载入器关系

在Java中。我们用全然匹配类名来标识一个类。即用包名和类名。而在JVM中。一个类由全然匹配类名和一个类载入器的实例ID作为唯一标识。

即是说同一个虚拟机能够有两个包名、类名都相同的类。仅仅要他们由两个不同类载入器载入。

于是当我们在Java中常常说两个类相不相等,必须是针对同一个类载入器载入的前提下才有意义。否则就算是相同的字节代码,由不同类载入器载入,这两个类也不是相等的。这样的特征为我们提供了隔离机制,在tomcatserver中是十分实用的。

了解了JVM的类载入器的各种机制后,看看一个类是如何被类载入器载入进来的。一个类准备载入,类载入器先推断此类是否已经被载入过(载入过的类会被缓存在内存中),假设缓存中存在此类则直接返回这个类。

否则获取父类载入器,假设父类载入器为null,则由Bootstrap ClassLoader载入并返回Class。假设父类载入器不为null,则由父类载入器载入。载入成功就返回Class,载入失败则依据类路径查找class文件,找到就载入此class并返回Class,找不到就抛出ClassNotFoundException异常。

图2-4-2 类载入过程

类载入器属于JVM级别的设计,我们非常多时候基本不会跟他打交道,可是假如你想了解整个JAVA体系是怎样工作的,假如你要设计开发自己的框架或中间件或一个较庞大的java软件。那么你必须熟悉类载入器的相关机制,在现实的设计中,依据实际情况利用类载入器能够提供类库的隔离及共享,保证你的软件不同级别的逻辑切割程序不会互相影响,提供更好的安全性。

喜欢研究java的同学能够交个朋友,以下是本人的微信号:

java类载入器——ClassLoader的更多相关文章

  1. Java类载入器 ClassLoader的解析

    //參考 : http://www.ibm.com/developerworks/cn/java/j-lo-classloader/ 类载入器基本概念 类载入器是 Java 语言的一个创新,也是 Ja ...

  2. Java类载入器原理分析

    一:Java虚拟机中能够安装多个类载入器,系统默认是三个基本的类载入器: Bootstrap  ExtClassLoader  AppClassLoader 类载入器也是Java类.由于其它Java类 ...

  3. Java类载入器(一)——类载入器层次与模型

    类载入器   虚拟机设计团队把类载入阶段中的"通过一个类的全限定名来获取描写叙述此类的二进制字节流"这个动作放到Java虚拟机外部去实现.以便让应用程序自己决定怎样去获取所须要的类 ...

  4. Java类载入器(二)——自己定义类载入器

      用户定制自己的ClassLoader能够实现以下的一些应用: 自己定义路径下查找自己定义的class类文件,或许我们须要的class文件并不总是在已经设置好的Classpath以下,那么我们必须想 ...

  5. Java类载入器

    1.   系统载入器简单介绍 Java虚拟机中能够安装多个类载入器,系统默认三个主要类载入器(BootStrap.ExtClassLoader.AppClassLoader).每一个类载入器负责载入特 ...

  6. 黑马程序猿——Java中的类载入器

    ------- android培训.java培训.期待与您交流! -------- 类载入器 Java虚拟机中能够安装多个类载入器,系统默认三个主要类载入器,每一个类负责载入特定位置的类: BootS ...

  7. 深入研究Java类载入机制

    深入研究Java类载入机制   类载入是Java程序运行的第一步,研究类的载入有助于了解JVM运行过程,并指导开发人员採取更有效的措施配合程序运行. 研究类载入机制的第二个目的是让程序能动态的控制类载 ...

  8. Tomcat类载入器机制(Tomcat源代码解析六)

    要说Tomcat的Classloader机制,我们还得从Bootstrap開始.在BootStrap初始化的时候.调用了org.apache.catalina.startup.Bootstrap#in ...

  9. Jboss7类载入器

    1. 类载入器理论知识介绍 类载入器基于Jboss Module,代替了层次类载入环境,避免了当类存在多个版本号时,导致类载入错误. 类载入是基于模块的.必须显示的定义模块依赖.部署也是模块化的,假设 ...

随机推荐

  1. php中session和cookie的使用及区别

    1.cookie的使用 什么是 Cookie? cookie 常用于识别用户.cookie 是服务器留在用户计算机中的小文件.每当相同的计算机通过浏览器请求页面时,它同时会发送 cookie.通过 P ...

  2. LeetCode(171) Excel Sheet Column Number

    题目 Related to question Excel Sheet Column Title Given a column title as appear in an Excel sheet, re ...

  3. C#基于引用创建单链表

    在C语言,单链表的实现依赖指针,指针用来指向节点,那么,用C#实现,自然就想到引用,节点的引用不就类似于指向Node的指针嘛

  4. Spring核心技术(十)——JSR-330标准注解

    从Spring 3.0开始,Spring开始支持JSR-330标准的注解(依赖注入).这些注解和Spring注解扫描的方式是一直的,开发者只需要在classpath中配置相关的jar包即可. 如果开发 ...

  5. ES6(函数新增特性)

    ES6(函数新增特性) 1.函数参数默认值 没有 y 时,默认就是world 有 y 时,输出值即可 (错误) (C有默认值,正确) 默认值后面不能再有没有默认值的变量 2.作用域 y 取其前面的 x ...

  6. 谷歌浏览器修改CSS和js后同步保存到文件中 (译)

    本文标题:谷歌浏览器修改CSS和js后同步保存到文件中. 文本作者:魔芋铃. 英文原文:http://www.stephensaw.me/google-chrome-devtools-source-m ...

  7. Uva10294 Arif in Dhaka (置换问题)

    扯回正题,此题需要知道的是置换群的概念,这点在刘汝佳的书中写的比较详细,此处不多做赘述.此处多说一句的是第二种手镯的情况.在下图中“左图顺时针转1个位置”和“右图顺时针旋转5个位置”是相同的,所以在最 ...

  8. 2016 Multi-University Training Contest 3 solutions BY 绍兴一中

    1001 Sqrt Bo 由于有\(5\)次的这个限制,所以尝试寻找分界点. 很容易发现是\(2^{32}\),所以我们先比较输入的数字是否比这个大,然后再暴力开根. 复杂度是\(O(\log\log ...

  9. 巴蜀4384 -- 【模拟试题】作诗(Poetize)

    Description 神犇SJY虐完HEOI之后给傻×LYD出了一题:SHY是T国的公主,平时的一大爱好是作诗.由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次, ...

  10. 《TCP/IP详解卷1:协议》——第3章 IP:网际协议(转载)

    1.引言 IP是TCP/IP协议族中最核心的协议.所有的TCP.UDP.ICMP及IGMP数据都以IP数据报格式传输.IP提供不可靠. 无连接的数据报传送服务. (1)不可靠 它不能保证IP数据报能成 ...