类加载器(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. Mina2 研究总结

    一.Mina框架. Mina的框架大概是这么个样子: 底层由Java 的NIO 1.0实现 核心架构应该是这样: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZX ...

  2. Python 新浪微博元素 (Word, Screen Name)词汇多样性

    CODE: #!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2014-7-10 @author: guaguastd @name: w ...

  3. Python爬行动物(一):基本概念

    定义网络爬虫          网络爬虫(Web Spider,也被称为网络蜘蛛,网络机器人,也被称为网页追逐者).按照一定的规则,维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁,自己主动索引 ...

  4. 居然还有FindFirstChangeNotification函数

    http://download.csdn.net/download/sololie/5966243

  5. JS Bin Tips and Bits • About

    JS Bin Tips and Bits • About   About Who built this? JS Bin was built by Remy Sharp and is completel ...

  6. linux ifconfig命令使用详解

    Linux下网卡命名规律:eth0,eth1.第一块以太网卡,第二块.lo为环回接口,它的IP地址固定为127.0.0.1,掩码8位.它代表你的机器本身. 1.ifconfig是查看网卡的信息. if ...

  7. 通过Type.InvokeMethod实现方法的重载

    版本:.NET Framework 3.5 先来一个反射调用方法的例子: using System; using System.Reflection; class Example { static v ...

  8. hdu2112 HDU Today

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2112 题目分类:SPFA算法+map容器 错误点:红色标记部分 代码: #include<bit ...

  9. HDU 2112 HDU Today(Dijkstra)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2112 HDU Today Time Limit: 15000/5000 MS (Java/Others ...

  10. Lua 解释器

    Lua 解释器 警告⚠️:这将是一个又臭又长的系列教程,教程结束的时候,你将拥有一个除了性能差劲.扩展性差.标准库不完善之外,其他方面都和官方相差无几的 Lua 语言解释器.说白了,这个系列的教程实现 ...