类加载器(class loader)用于装载 Java 类到 Java 虚拟机中。一般来说。Java 虚拟机使用 Java 类的方式例如以下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类载入器负责读取
Java 字节代码。并转换成java.lang.Class类的一个实例。每一个这种实例用来表示一个
Java 类。

通过此实例的 newInstance()方法就能够创建出该类的一个对象,也就是万能的Class对象。

Java 中的类载入器大致能够分成两类。一类是系统提供的,另外一类则是由 Java 应用开发者编写的。系统提供的类载入器主要有以下三个:

  • 引导类载入器(bootstrap class loader):它用来载入 Java 的核心库。是用原生代码来实现的。并不继承自 java.lang.ClassLoader
  • 扩展类载入器(extensions class loader):它用来载入 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库文件夹。该类载入器在此文件夹里面查找并载入 Java 类。

  • 系统类载入器(system class loader):它依据 Java 应用的类路径(CLASSPATH)来载入 Java 类。一般来说,Java 应用的类都是由它来完毕载入的。

    能够通过 ClassLoader.getSystemClassLoader()来获取它。

以下这段代码的输出结果能够显示出classloader的树状组织结构。
public class ClassLoaderTest {
public static void main(String[] args){
ClassLoader loader = ClassLoaderTest.class.getClassLoader();
while (loader != null) {
System.out.println(loader.toString());
loader = loader.getParent();
}
}
}

当中loader,toString()方法的返回值等同于以下的表达式:

 getClass().getName() + '@' + Integer.toHexString(hashCode())

程序的输出例如以下:

sun.misc.Launcher$AppClassLoader@70a0afab

sun.misc.Launcher$ExtClassLoader@456d3d51

第一个输出的是 ClassLoaderTree类的类载入器,即系统类载入器。它是 sun.misc.Launcher$AppClassLoader类的实例;第二个输出的是扩展类载入器。是 sun.misc.Launcher$ExtClassLoader类的实例。

须要注意的是这里并没有输出引导类载入器。这是因为有些
JDK 的实现对于父类载入器是引导类载入器的情况,getParent()方法返回 null

在了解了类载入器的树状组织结构之后,以下介绍类载入器的代理模式。

classloader 载入类用的是全盘负责托付机制。所谓全盘负责,即是当一个classloader载入一个Class的时候,这个Class所依赖的和引用的全部
Class也由这个classloader负责载入。除非是显式的使用另外一个classloader载入;托付机制则是先让parent(父)类载入器 (而不是super,它与parent classloader类不是继承关系)寻找。仅仅有在parent找不到的时候才从自己的类路径中去寻找。

此外类载入还採用了cache机制。也就是假设 cache中保存了这个Class就直接返回它,假设没有才从文件里读取和转换成Class,并存入cache。这就是为什么我们改动了Class可是必 须又一次启动JVM才干生效的原因。



每一个ClassLoader载入Class的过程是:

1.检測此Class是否加载过(即在cache中是否有此Class),假设有到8,假设没有到2

2.假设parent classloader不存在(没有parent,那parent一定是bootstrap classloader了),到4。假设存在。到3

3.请求parent classloader加载,假设成功到8。不成功到5

4.请求jvm从bootstrap classloader中加载,假设成功到8

5.寻找Class文件(从与此classloader相关的类路径中寻找)。找到了到6。假设找不到则到7.

6.从文件里加载Class,到8.

7.抛出ClassNotFoundException.

8.返回Class.

总结一下。类载入器的顺序是:

先是bootstrap classloader。然后是extension classloader,最后才是system classloader。这样做的原因是出于安全性的考虑。试想假设system classloader“亲自”载入了一个具有破坏性的“java.lang.System”类的后果吧。

这种托付机制保证了用户即使具有一个这种类, 也把它增加到了类路径中,可是它永远不会被载入。由于这个类总是由bootstrap
classloader来载入的。大家能够运行一下下面的代码:

   System.out.println(System.class.getClassLoader());

将会看到结果是null,这就表明java.lang.System是由bootstrap classloader载入的,由于bootstrap classloader不是一个真正的ClassLoader实例。而是由JVM实现的,正如前面已经说过的。

简而言之,就是自底向上检查类是否已经被载入,然后自顶向下尝试载入类。

值得一提的是tomcat的webappclassloader 这个相当于用户自己定义载入器,为每一个部署在独立tomcat实例上的web应用而创建。该载入器载入的类对于自身应用中的类都是可见的但对于其它web应用不可见,它负责载入以下路径中的类

/WEB-INF/classes

/WEB-INF/lib

和java中的载入类的代理模式方式不同,webapp类载入器採用的是还有一种类载入模式(Servlet 2.4规范9.7.2节 web Application Classloader中建议使用这样的方式),当一个request对象载入一个由webappClassloader负责载入的类时,webappClassloader
将首先在本地库(WEB-INF)进行搜索。与传统的托付给父载入器进行搜索的方式不同。

潜水 java类加载器ClassLoader的更多相关文章

  1. 深入理解Java类加载器(ClassLoader)

    深入理解Java类加载器(ClassLoader) Java学习记录--委派模型与类加载器 关于Java类加载双亲委派机制的思考(附一道面试题) 真正理解线程上下文类加载器(多案例分析) [jvm解析 ...

  2. 深入理解Java类加载器(ClassLoader) (转)

    转自: http://blog.csdn.net/javazejian/article/details/73413292 关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Ja ...

  3. Java 类加载器(ClassLoader)

    类加载器 ClassLoader 什么是类加载器? 通过一个类的全限定名来获取描述此类的二进制字节流这个动作放到Java虚拟机外部去实现, 以便让应用程序自己决定如何去获取所需要的类.实现这个动作的代 ...

  4. 浅析java类加载器ClassLoader

    作为一枚java猿,了解类加载器是有必要的,无论是针对面试还是自我学习. 本文从JDK提供的ClassLoader.委托模型以及如何编写自定义的ClassLoader三方面对ClassLoader做一 ...

  5. java类加载器——ClassLoader

    Java的设计初衷是主要面向嵌入式领域,对于自定义的一些类,考虑使用依需求加载原则,即在程序使用到时才加载类,节省内存消耗,这时即可通过类加载器来动态加载. 如果你平时只是做web开发,那应该很少会跟 ...

  6. Java类加载器ClassLoader总结

    JAVA类装载方式,有两种: 1.隐式装载, 程序在运行过程中当碰到通过new 等方式生成对象时,隐式调用类装载器加载对应的类到jvm中. 2.显式装载, 通过class.forname()等方法,显 ...

  7. Java类加载器(ClassLoader)

    类加载的机制的层次结构 每个编写的”.java”拓展名类文件都存储着需要执行的程序逻辑,这些”.java”文件经过Java编译器编译成拓展名为”.class”的文件,”.class”文件中保存着Jav ...

  8. Java类加载器(死磕5)

    Java类加载器(  CLassLoader )  死磕5:  自定义一个文件系统classLoader 本小节目录 5.1. 自定义类加载器的基本流程 5.2. 入门案例:自定义文件系统类加载器 5 ...

  9. Java类加载器( 死磕9)

    [正文]Java类加载器(  CLassLoader ) 死磕9:  上下文加载器原理和案例 本小节目录 9.1. 父加载器不能访问子加载器的类 9.2. 一个宠物工厂接口 9.3. 一个宠物工厂管理 ...

随机推荐

  1. Struts2 学习笔记18 拦截器原理分析

    我们来进行一下拦截器的原理分析,从Struts2的源代码开始,然后我们手动创建一个项目进行模拟.(源代码需要下载然后添加好才能看到)我们可以用Debug来读源码. 从doFilter开始执行,流程如图 ...

  2. Swift - 多行文本输入框(UITextView)的用法

    1,多行文本控件的创建 1 2 3 4 var textview=UITextView(frame:CGRectMake(10,100,200,100)) textview.layer.borderW ...

  3. C++ 多源码文件简单组织

    C++ 多源码文件简单组织 基本上和C的是一样的,只不过C++的方法要在类中声明.看一个简单实例.ainimal.h  类里面对外公开的信息. 点击(此处)折叠或打开 #ifndef _ANIMAL_ ...

  4. linux串口编程总结

    串口本身.标准和硬件 † 串口是计算机上的串行通讯的物理接口.计算机历史上,串口以前被广泛用于连接计算机和终端设备和各种外部设备.尽管以太网接口和USB接口也是以一个串行流进行数据传送的.可是串口连接 ...

  5. [Xcode]some little skill

    Date:2014-1-2 Summary: 自己在使用Xcode的一些小习惯,记录下来,我是这么用的,你呢? Contents:1.使用#warning 在工作中,难免需要做一些test,但是又怕忘 ...

  6. 在HTML中如何隐藏某段文字具体该怎么实现

    <p style="display:none;"> 需要隐藏的文字....... </p> <div style="display:none ...

  7. 【机器学习实验】学习Python来分类现实世界的数据

    引入 一个机器能够依据照片来辨别鲜花的品种吗?在机器学习角度,这事实上是一个分类问题.即机器依据不同品种鲜花的数据进行学习.使其能够对未标记的測试图片数据进行分类. 这一小节.我们还是从scikit- ...

  8. jquery ajax协调SpringMVCD实现局部刷新IV

    feedback.jsp: <%@ page language="java" import="java.util.*" pageEncoding=&quo ...

  9. A股市场暴跌背后的三大元凶?

    周一两市低开低走,盘中空方连续打压股指,大盘一路下行,沪指2000点关口告急,收于1963.24点,跌幅超过了5%.行业板块全线溃败.银行.证券领衔大幅杀跌,板块跌幅一度超过5%:继上周五中国石油A股 ...

  10. 上下文菜单与TrackPopupMenu

    这算是一个演示程序吧,想不到上下文菜单也是採用ON_COMMAND宏来进行消息映射,在这里,我发现一个问题:从CWnd派生的类ON_UPDATE_COMMAND_UI_RANGE似乎没有效果,不知道应 ...