`

ClassLoader的工作原理

阅读更多
ClassLoader的工作原理

每个运行中的线程都有一个成员contextClassLoader,用来在运行时动态地载入其它类
系统默认的contextClassLoader是systemClassLoader,所以一般而言java程序在执行时可以使用JVM自带的类、$JAVA_HOME/jre/lib/ext/中的类和$CLASSPATH/中的类
可以使用Thread.currentThread().setContextClassLoader(...);更改当前线程的contextClassLoader,来改变其载入类的行为

ClassLoader被组织成树形,一般的工作原理是:
1) 线程需要用到某个类,于是contextClassLoader被请求来载入该类
2) contextClassLoader请求它的父ClassLoader来完成该载入请求
3) 如果父ClassLoader无法载入类,则contextClassLoader试图自己来载入

Java中一共有四个类加载器,之所以叫类加载器,是程序要用到某个类的时候,要用类加载器载入内存。
    这四个类加载器分别为:Bootstrap ClassLoader、Extension ClassLoader、AppClassLoader
和URLClassLoader,他们的作用其实从名字就可以大概推测出来了。其中AppClassLoader在很多地方被叫做System ClassLoader

Bootstrap ClassLoader是在JVM开始运行的时候加载java的核心类,是用C++编写的,它用来加载核心类库,在JVM源代码中这样写道:
static const char classpathFormat[] =
"%/lib/rt.jar:"
"%/lib/i18n.jar:"
"%/lib/sunrsasign.jar:"
"%/lib/jsse.jar:"
"%/lib/jce.jar:"
"%/lib/charsets.jar:"
"%/classes";
Extension ClassLoader是用来加载扩展类,即/lib/ext中的类。
AppClassLoader用来加载Classpath的类,是和我们关系最密切的类。
URLClassLoader用来加载网络上远程的类

1. 预先加载与依需求加载

Java 运行环境为了优化系统,提高程序的执行速度,在 JRE 运行的开始会将 Java 运行所需要的基本类采用预先加载( pre-loading )的方法全部加载要内存当中,因为这些单元在 Java 程序运行的过程当中经常要使用的,主要包括 JRE 的 rt.jar 文件里面所有的 .class 文件。

当 java.exe 虚拟机开始运行以后,它会找到安装在机器上的 JRE 环境,然后把控制权交给 JRE , JRE 的类加载器会将 lib 目录下的 rt.jar 基础类别文件库加载进内存,这些文件是 Java 程序执行所必须的,所以系统在开始就将这些文件加载,避免以后的多次 IO 操作,从而提高程序执行效率。

相对于预先加载,我们在程序中需要使用自己定义的类的时候就要使用依需求加载方法( load-on-demand ),就是在 Java 程序需要用到的时候再加载,以减少内存的消耗,因为 Java 语言的设计初衷就是面向嵌入式领域的。

2. 隐式加载和显示加载

Java 的加载方式分为隐式加载( implicit )和显示加载( explicit ),上面的例子中就是用的隐式加载的方式。所谓隐式加载就是我们在程序中用 new 关键字来定义一个实例变量, JRE 在执行到 new 关键字的时候就会把对应的实例类加载进入内存。隐式加载的方法很常见,用的也很多, JRE 系统在后台自动的帮助用户加载,减少了用户的工作量,也增加了系统的安全性和程序的可读性。
 Class c = Class.forName("TestClass"); 

  TestClass object = (TestClass)c.newInstance(); 

 object.method(); 

通过 Class 类的 forName (String s) 方法把自定义类 TestClass 加载进来,并通过 newInstance ()方法把实例初始化。事实上 Class 类还很多的功能,这里就不细讲了,有兴趣的可以参考 JDK 文档。

Class 的 forName() 方法还有另外一种形式: Class forName(String s, boolean flag, ClassLoader classloader) , s 表示需要加载类的名称, flag 表示在调用该函数加载类的时候是否初始化静态区, classloader 表示加载该类所需的加载器。

forName (String s) 是默认通过 ClassLoader.getCallerClassLoader() 调用类加载器的,但是该方法是私有方法,我们无法调用,如果我们想使用 Class forName(String s, boolean flag, ClassLoader classloader) 来加载类的话,就必须要指定类加载器,可以通过如下的方式来实现:

Test test = new Test();//Test 类为自定义的一个测试类;

ClassLoader cl = test. getClass().getClassLoader();

                         // 获取 test 的类装载器;

Class c = Class.forName("TestClass", true, cl);

因为一个类要加载就必需要有加载器,这里我们是通过获取加载 Test 类的加载器 cl 当作加载 TestClass 的类加载器来实现加载的。
3. 自定义类加载机制

之前我们都是调用系统的类加载器来实现加载的,其实我们是可以自己定义类加载器的。利用 Java 提供的 java.net.URLClassLoader 类就可以实现。下面我们看一段范例:

    try{

               URL url = new URL("file:/d:/test/lib/");

               URLClassLoader urlCL = new URLClassLoader(new URL[]{url});

               Class c = urlCL.loadClass("TestClassA");

               TestClassA object = (TestClassA)c.newInstance();

               object.method();

        }catch(Exception e){

               e.printStackTrace();

        }

我们通过自定义的类加载器实现了 TestClassA 类的加载并调用 method ()方法。分析一下这个程序:首先定义 URL 指定类加载器从何处加载类, URL 可以指向网际网络上的任何位置,也可以指向我们计算机里的文件系统 ( 包含 JAR 文件 ) 。上述范例当中我们从 file:/d:/test/lib/ 处寻找类;然后定义 URLClassLoader 来加载所需的类,最后即可使用该实例了。

4. 类加载器的阶层体系

讨论了这么多以后,接下来我们仔细研究一下 Java 的类加载器的工作原理:

当执行 java ***.class 的时候, java.exe 会帮助我们找到 JRE ,接着找到位于 JRE 内部的 jvm.dll ,这才是真正的 Java 虚拟机器 , 最后加载动态库,激活 Java 虚拟机器。虚拟机器激活以后,会先做一些初始化的动作,比如说读取系统参数等。一旦初始化动作完成之后,就会产生第一个类加载器―― Bootstrap Loader , Bootstrap Loader 是由 C++ 所撰写而成,这个 Bootstrap Loader 所做的初始工作中,除了一些基本的初始化动作之外,最重要的就是加载 Launcher.java 之中的 ExtClassLoader ,并设定其 Parent 为 null ,代表其父加载器为 BootstrapLoader 。然后 Bootstrap Loader 再要求加载 Launcher.java 之中的 AppClassLoader ,并设定其 Parent 为之前产生的 ExtClassLoader 实体。这两个加载器都是以静态类的形式存在的。这里要请大家注意的是, Launcher$ExtClassLoader.class 与 Launcher$AppClassLoader.class 都是由 Bootstrap Loader 所加载,所以 Parent 和由哪个类加载器加载没有关系。
这三个加载器就构成我们的 Java 类加载体系。他们分别从以下的路径寻找程序所需要的类:

BootstrapLoader : sun.boot.class.path

ExtClassLoader:      java.ext.dirs

AppClassLoader:      java.class.path

这三个系统参量可以通过 System.getProperty() 函数得到具体对应的路径。
分享到:
评论

相关推荐

    ClassLoader类加载机制和原理详解

    本文将深入探讨ClassLoader的工作原理和类加载机制,帮助开发者理解这个至关重要的概念。 1. 类加载机制概述 Java的类加载机制遵循“双亲委派模型”(Delegation Model)。当一个类被加载时,它首先会尝试由当前...

    Java ClassLoader Tutorial.zip

    这个教程将深入探讨ClassLoader的工作原理、类型以及如何自定义类加载器。 一、Java ClassLoader 基础 1. 类加载过程:Java中的类加载分为三个阶段——加载、验证、准备、解析和初始化。ClassLoader主要参与的是...

    ClassLoader原理

    ClassLoader原理的理解对于深入学习Java和进行系统优化至关重要。这篇博文将带你深入了解ClassLoader的工作机制。 首先,我们来理解ClassLoader的基本概念。ClassLoader是一个抽象的概念,它是Java中的一个接口,...

    Tomcat 5.0.18 ClassLoader source code insight

    下面,我们将详细探讨Tomcat 5.0.18版本中的ClassLoader工作原理。 首先,ClassLoaders在Java中起着至关重要的作用,它们负责查找和加载类到JVM中。Tomcat的ClassLoader设计独特,因为它需要处理Web应用程序的隔离...

    java classLoader 的全面讲解

    二、ClassLoader 工作原理 1. 类的唯一标识:类在JVM中的唯一标识是由全限定名(包名+类名)和加载它的类加载器共同决定的,这允许同名类在不同类加载器下不冲突。 2. 类的查找与加载:类加载器根据类的全限定名在...

    Java ClassLoader原理

    ### Java ClassLoader原理详解 #### 摘要 本文探讨了Java虚拟机(JVM)中的一个重要特性:动态类加载(Dynamic Class Loading)。这一机制为Java平台提供了强大的能力,允许在运行时安装软件组件,例如从网络下载...

    【图解版】深入分析ClassLoader类加载工作机制

    【图解版】深入分析ClassLoader类加载工作机制,从原理到JVM的装载过程,详情分析了ClassLoader加载类以及自定义类加载器的过程,不可用于商业用途,如有版权问题,请联系删除!

    理解Java ClassLoader机制

    理解ClassLoader的工作原理对于优化应用性能、处理类加载问题以及实现自定义加载器至关重要。 首先,我们来了解一下ClassLoader的基本层次结构。在Java中,ClassLoader分为三个主要层次:Bootstrap ClassLoader、...

    webshpere classloader 原理

    ### WebSphere ClassLoader原理 #### 一、概述 在探讨WebSphere Application Server v6中的ClassLoaders之前,我们首先简要回顾一下ClassLoaders的基本概念及其在Java虚拟机(JVM)中的作用。 **ClassLoaders**是...

    JAVA工程师实习一周总结【推荐下载】.doc

    在实习期间,我尝试编写了自己的类加载器,这不仅加深了我对ClassLoader工作原理的理解,也锻炼了我的编程实践能力。这个过程让我认识到,作为一名JAVA工程师,不仅要掌握基本的语法和框架,还要理解JVM的底层运作,...

    classloader

    学习ClassLoader的工作原理以及如何创建自己的ClassLoader是必要的。 首先,让我们深入了解ClassLoader的基本概念。在传统编程语言中,如C或C++,程序通常是一个单一的可执行文件,而Java则不同,它的编译结果是以...

    Java ClassLoader定制实例

    理解ClassLoader的工作原理以及如何定制它,对于深入学习Java的运行机制和进行高级应用开发具有重要意义。本篇文章将深入探讨Java ClassLoader的内部工作,并通过一个具体的实例来展示如何定制自己的ClassLoader。 ...

    ClassLoader 详解.doc

    深入理解ClassLoader的工作原理对于优化应用性能、解决类加载问题以及实现自定义加载策略至关重要。 首先,JVM启动时,会构建一个类加载器的层次结构,主要包括三个基本类加载器: 1. Bootstrap ClassLoader:引导...

    自定义classloader的使用

    一、Classloader的工作原理 Java的类加载机制遵循双亲委派模型,即当一个类加载器需要加载类时,它首先委托父类加载器尝试加载,只有当父类加载器无法加载时,才会尝试自己加载。这种设计避免了类的重复加载,并...

    Android 使用classloader原理进行热更新

    热更新通常依赖于类加载器(Classloader)的工作原理来实现,本篇文章将深入探讨如何利用Android的类加载器实现热更新的机制。 首先,我们需要理解什么是类加载器。在Java和Android中,类加载器是负责查找、加载和...

    ClassLoader加载机制

    该电子书详细介绍了java虚拟机类加载机制,对于深入理解jvm工作原理有很好的帮助作用,对于初学java,有一定工作经验的小伙伴来说是一本提高自身java素养,夯实自己java基本技能的“葵花宝典”。

    ClassLoader小例子

    本示例"ClassLoader小例子"将深入探讨这个概念,并通过一个具体的程序来演示其工作原理。下面我们将详细讨论ClassLoader的基本概念、工作流程以及如何自定义ClassLoader。 1. **ClassLoader的基本概念** - 类加载...

    java ClassLoader机制及其在OSGi中的应用

    理解ClassLoader的工作原理对于优化Java应用程序性能以及解决类冲突等问题具有重要意义。 一、ClassLoader的基本概念 Java程序由多个类组成,每个类对应一个.class文件。当程序运行时,ClassLoader根据需要动态...

    JVM ClassLoader简析

    本文将深入浅出地探讨JVM ClassLoader的工作原理和相关知识点。 首先,ClassLoader可以分为三种基本类型:Bootstrap ClassLoader、Extension ClassLoader和Application ClassLoader。Bootstrap ClassLoader是JVM...

Global site tag (gtag.js) - Google Analytics