参考:http://www.importnew.com/6581.html

Java 编译器会为虚拟机转换源指令。虚拟机代码存储在以 .class 为扩展名的类文件中,每个类文件都包含某个类或者接口的定义和代码实现。这些类文件必须由一个程序进行解释,该程序能够将虚拟机的指令集翻译成目标机器的机器语言。

虚拟机值加载程序执行时所需要的类文件。

类加载机制并非只使用单个的类加载器。每个 Java 程序至少拥有三个类加载器:

引导类加载器

扩展类加载器

系统类加载器(有时也称为应用类加载器)

引导类加载器负责加载系统类(通常从 JAR 文件 rt.jar 中进行加载)。它是虚拟机不可分割的一部分,而且通常是用 C 语言来实现的。引导类加载器没有对应的 ClassLoader 对象。

扩展类加载器用于从 jre/lib/ext 目录加载 “标准的扩展”。可以将 JAR 文件放入该目录,这样即使没有任何类路径,扩展类加载器也可以找到其中的各个类。

系统类加载器用于加载应用类。它在由 CLASSPATH 环境变量或者 -classpath 命令行选项设置的类路径中的目录里或者是 JAR/ZIP 文件里查找这些类。

在 Oracle 的 Java 语言实现中,扩展类加载器和系统类加载器都是用 Java 来实现的。它们都是 URLClassLoader 类的实例。

警告:如果将 JAR 文件放入 jre/lib/ext 目录中,并且在它的类中有一个类需要调用系统类或者扩展类,那么就会遇到麻烦。扩展类加载器并不使用类路径。

除了所有已经提到的位置,还可以从 jre/lib/endorsed 目录中加载类。这种机制只能用于将某个标准的 Java 类库替换为更新的版本(例如那些支持 XML 和 CORBA 的类)。

类加载器有一种父/子关系。除了引导类加载器外,每个类加载器都有一个父类加载器。根据规定,类加载器会为它的父类加载器提供一个机会,以便加载任何给定的类,并且只有在其父类加载器加载失败时,它才会加载该给定类。

某些程序具有插件架构,其中代码的某些部分是作为可选的插件打包的。如果插件被打包为 JAR 文件,那就可以直接用 URLClassLoader 类的实例去加载这些类。

 package classloader;

 import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader; public class URLDemo { public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, InstantiationException, IllegalAccessException {
URL url= new URL("file:\\E:\\project_neon1\\Demo2\\commons-codec-1.9.jar");
URLClassLoader pluginLoader = new URLClassLoader(new URL[] {url});
Class<?> c1 = pluginLoader.loadClass("org.apache.commons.codec.binary.Base64");
} }

因为在 URLClassLoader 构造器中没有指定父类加载器,因此 pluginLoader 的父亲就是系统类加载器。

大多数时候,你不必操心类加载的层次结构。通常,类是由于其他的类需要它而被加载的,而这个过程对你是透明的。

偶尔,你也会需要干涉和指定类加载器。

考虑下面的例子:

你的应用的代码包含一个助手方法,它要调用 Class.forName(classNameString)。

这个方法是从一个插件类中被调用的。

而 classNameString 指定的正是一个包含在这个插件的 JAR 中类。

插件的作者很合理地期望这个类应该被加载。但是,助手方法的类是由系统类加载器加载的,这正式 Class.forName 所使用的类加载器。而对于它来说,在插件 JAR 中的类是不可视的,这种现象被称为类加载器倒置。

要解决这个问题,助手方法需要使用恰当的类加载器,它可以要求类加载器作为其一个参数传递给他。或者,它可以要求将恰当的类加载器设置成为当前线程的上下文类加载器。

每个线程都有一个对类加载器的引用,称为上下文类加载器。主线程的上下文类加载器是系统类加载器。当新线程创建时,它的上下文类加载器会被设置成为创建该线程的上下文类加载器。因此,如果你不做任何特殊的操作,那么所有线程就都将它们的上下文类加载器设置为系统类加载器。

可以通过下面的调用将上下文类加载器设置成为任何类加载器。

 Thread t = Thread.currentThread();
t.setContextClassLoader(loader);

然后助手方法可以获取这个上下文类加载器:

 Thread t = Thread.currentThread();
ClassLoader loader = t.getContextClassLoader();
Class cl = loaser.loadClass(className);

当上下文类加载器设置为插件类加载器时,问题依旧存在。应用设计者必须作出决策:通常,当调用由不同的类加载器加载的插件类的方法时,进行上下文类加载器的设置是一种好的思路;或者,让助手方法的调用者设置上下文类加载器。

如果你编写了一个按名字来加载类的方法,那么让调用者在传递显示的类加载器和使用上下文类加载器之间进行选择就是一种好的做法。不要直接使用该方法所属的类的类加载器。

在同一个虚拟机中,可以有两个类,它们的类名和包名都是相同的。类是由它的全名和类的加载器来确定的。这项技术在加载来自多处的代码时很有用。例如 servlets 和 EJB 的 “热部署”。

我们可以编写自己的用于特殊目的的类加载器,这使得我们可以在向虚拟机传递字节码之前执行定制的检查。

如果要编写自己的类加载器,只需要继承 ClassLoader 类,然后覆盖下面这个方法

findClass(String className)

ClassLoader 超类的 loadClass 方法用于将类的加载操作委托给其父类加载器去进行,只有当该类尚未加载并且父类加载器也无法加载该类时,才调用 findClass 方法。

如果要实现该方法,必须做到以下几点:

1) 为来自本地文件系统或者其他来源的类加载其字节码

2) 调用 ClassLoader 超类的 defineClass 方法,向虚拟机提供字节码

JavaSE--类加载器的更多相关文章

  1. javaSE高级篇4 — 反射机制( 含类加载器 ) — 更新完毕

    反射机制 1.反射机制是什么?----英文单词是:reflect.在java.lang包下---这才是java最牛逼的技术 首先提前知道一句话----在java中,有了对象,于是有了类,那么有了类之后 ...

  2. 第42天学习打卡(Class类 Class类的常用方法 内存分析 类的加载过程 类加载器 反射操作泛型 反射操作注解)

    Class类 对象照镜子后得到的信息:某个类的属性.方法和构造器.某个类到底实现了哪些接口.对于每个类而言,JRE都为其保留一个不变的Class类型的对象.一个Class对象包含了特定某个结构(cla ...

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

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

  4. Java中的类加载器

    转载:http://blog.csdn.net/zhangjg_blog/article/details/16102131 从java的动态性到类加载机制   我们知道,Java是一种动态语言.那么怎 ...

  5. Java基础-类加载机制与自定义类Java类加载器(ClassLoader)

    Java基础-类加载机制与自定义类Java类加载器(ClassLoader) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 关于类加载器的概念和分类我就不再废话了,因为我在之前的笔 ...

  6. Java虚拟机类加载器及双亲委派机制

    所谓的类加载器(Class Loader)就是加载Java类到Java虚拟机中的,前面<面试官,不要再问我"Java虚拟机类加载机制"了>中已经介绍了具体加载class ...

  7. 彻底搞懂JVM类加载器:基本概念

    本文阅读时间大约9分钟. 写在前面 在Java面试中,在考察完项目经验.基础技术后,我会根据候选人的特点进行知识深度的考察,如果候选人简历上有写JVM(Java虚拟机)相关的东西,那么我常常会问一些J ...

  8. Java-JVM 自定义类加载器

    一.sun.misc.Launcher (ExtClassLoader 与 AppClassLoader 的创建) public Launcher() { Launcher.ExtClassLoade ...

  9. 深入理解java:1.1. 类加载器

    从java的动态性到类加载机制   我们知道,Java是一种动态语言. 那么怎样理解这个“动态”呢? 或者说一门语言具备了什么特性,才能称之为动态语言呢? 对于java,我是这样理解的. 我们都知道J ...

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

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

随机推荐

  1. UVA - 10954 Add All (全部相加)(Huffman编码 + 优先队列)

    题意:有n(n <= 5000)个数的集合S,每次可以从S中删除两个数,然后把它们的和放回集合,直到剩下一个数.每次操作的开销等于删除的两个数之和,求最小总开销.所有数均小于10^5. 分析:按 ...

  2. JS - 解决引入 js 文件无效的问题

    增加 type 即可  <script type="text/javascript" src="....js"></script>

  3. iOS 保存图片(视频)到相册

    1.C语言函数方式实现 注意:UIImageWriteToSavedPhotosAlbum方法必须实现代理方法,否则会崩溃. //参数1:图片对象 //参数2:成功方法绑定的target //参数3: ...

  4. tomcat的8080,8009,8443,8005都是什么端口

    <Server port="8005" shutdown="SHUTDOWN"> 远程停服务端口<Connector port="8 ...

  5. 2020/2/1 PHP代码审计之任意文件读取及删除漏洞

    在开始学习之前先简单记录一下自己现在的思路吧..现在接触的基本都是无防护的漏洞也就是最简单的一些漏洞.我的想法就是以代审思路为主,之前一直在打CTF,白盒的思维我觉得和CTF这种黑盒有很大区别.自己的 ...

  6. CountDownLatch和CyclicBarrier和Semaphore最通俗形象解释

    应该还有好多同学对这三个的区别比较模糊,网络上其他文章说的也比较专业化.所以我在这里举个例子说明这三个的区别. 我们假定有一场百米比赛,比赛包括十个运动员和一个裁判,每个运动员和每个裁判都是一个线程, ...

  7. 图像算法五:【图像小波变换】多分辨率重构、Gabor滤波器、Haar小波

    原 https://blog.csdn.net/alwaystry/article/details/52756051 图像算法五:[图像小波变换]多分辨率重构.Gabor滤波器.Haar小波 2018 ...

  8. 深入分析解决Deepin 15环境变量修改问题,完成JAVA环境搭建

    最近使用deepin配置JAVA环境时发现不论是修改/etc/profile还是 ~/.profile多次尝试后均无效,不得其解,最后通过官方论坛看到大神对deepin环境配置的解释,以及寻找到相关解 ...

  9. MyBatis 关联查询的实现:多对多

    2个实体:订单.商品,一个订单可以包含多种商品,同时一种商品可以属于多个订单,即多对多. 商品表goods_tb: 订单表order_tb: no是订单编号,user_id与用户表的id关联. 需要新 ...

  10. spring aop中的propagation的7种配置

    1.前言 在声明式的事务处理中,要配置一个切面,即一组方法,如 <tx:advice id="txAdvice" transaction-manager="txMa ...