ClassLoader的工作机制

java应用环境中不同的class分别由不同的ClassLoader负责加载。
一个jvm中默认的classloader有Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader,分别各司其职:

  • Bootstrap ClassLoader     负责加载java基础类,主要是 %JRE_HOME/lib/ 目录下的rt.jar、resources.jar、charsets.jar和class等
  • Extension ClassLoader      负责加载java扩展类,主要是 %JRE_HOME/lib/ext 目录下的jar和class
  • App ClassLoader           负责加载当前java应用的classpath中的所有类。

其中Bootstrap ClassLoader是JVM级别的,由C++撰写;Extension ClassLoader、App ClassLoader都是java类,都继承自URLClassLoader超类。
Bootstrap ClassLoader由JVM启动,然后初始化sun.misc.Launcher ,sun.misc.Launcher初始化Extension ClassLoader、App ClassLoader。

下图是ClassLoader的加载类流程图,以加载一个类的过程类示例说明整个ClassLoader的过程。


 Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader三者的关系如下:

Bootstrap ClassLoader是Extension ClassLoader的parent,Extension ClassLoader是App ClassLoader的parent。

但是这并不是继承关系,只是语义上的定义,基本上,每一个ClassLoader实现,都有一个Parent ClassLoader。

可以通过ClassLoader的getParent方法得到当前ClassLoader的parent。Bootstrap
ClassLoader比较特殊,因为它不是java class所以Extension
ClassLoader的getParent方法返回的是NULL。

了解了ClassLoader的原理和流程以后,我们可以试试自定义ClassLoader。


Java类加载器classLoader的工作机制

类加载器就是寻找类或接口字节码文件进行解析并构造JVM内部对象表示的组件。在Java中,类转载器把一个类装入JVM中,需要经过以下步骤:

1.装载:查找和导入Class文件;

2.链接: 执行校验、准备和解析步骤,其中解析步骤是可以选择的:

a)校验: 检查载入Class文件数据的正确性;

b)准备:给类的静态变量分配存储空间;

c)解析:将符号引用变成直接引用;

3.初始化:对类的静态变量、静态代码块进行初始化工作。

类装载工作是由ClassLoader及其之类负责的,ClassLoader是一个重要的Java运行时系统组件,它负责在运行时查找和装入Class 字节文件。JVM在运行时会产生三个ClassLoader:跟装载器、ExtClassLoader(扩展类装载器)和 AppClassLoader(系统类装载器)。其中,跟装载器不是ClassLoader的子类,它使用C++编写,因此我们在Java中看不到它,跟 装载器负责装载JRE的核心类库,如rt.jar,charsets.jar等。ExtClassLoader和AppClassLoader都是 ClassLoader的子类。其中ExtClassLoader负责装载JRE扩展目录ext中的JAR类包;AppClassLoader负责装载 ClassPath路径下的类包。

这三个类装载器之间存在父子层级关系,跟装载器是ExtClassLoader的父装载器,ExtClassLoader是AppClassLoader的父装载器。默认情况下,使用AppClassLoader装载应用程序的类,我们可以试验如下:

 public class ClassLoaderTest {

    public static void main(String[] args) {

    ClassLoader c=Thread.currentThread().getContextClassLoader();

    System.out.println(c);

    System.out.println(c.getParent());

    System.out.println(c.getParent().getParent());

    }

    }

运行结果如下:

[java]

sun.misc.Launcher$AppClassLoader@1016632

sun.misc.Launcher$ExtClassLoader@dc6a77

null

从上述结果可以分析得出当前的ClassLoader是AppClassloader,父ClassLoader是ExtClassLoader,祖父ClassLoader是根类装载器,因为在Java中无法获得它的句柄,因此返回null。

ClassLoader与Class.forName的区别

classLoader中的函数loadclass用于Class文件的加载但并没有完成初始化工作,而使用Class.forName则完成了初始化工作即完成对类的静态变量、静态代码块执行初始化工作。实例如下:

需要加载的类Reflect.java如下:

public class Reflect {

    private int userName;

    private int password;

    static {

    System.out.println("Reflect static block");

    }

    public Reflect(){

    System.out.println("Reflect constructs");

    }

    public int getUserName() {

    return userName;

    }

    public void setUserName(int userName) {

    this.userName = userName;

    }

    public int getPassword() {

    return password;

    }

    public void setPassword(int password) {

    this.password = password;

    }

    }

测试类Test.java如下:

public class Test {

    public static void main(String[] args) {

    ClassLoader classLoader=Thread.currentThread().getContextClassLoader();

    try {

    System.out.println("使用ClassLoader中的loadClass加载:");

    classLoader.loadClass("com.uestc.test.Reflect");

    System.out.println("使用Class.forName()加载:");

    Class.forName("com.uestc.test.Reflect");

    } catch (ClassNotFoundException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    }

运行结果如下:

[java]

使用ClassLoader中的loadClass加载:

使用Class.forName()加载:

Reflect static block

从上述结果可以看出loadClass并没有进行初始化工作,而Class.forName()进行了初始化工作。

java虚拟机学习-慢慢琢磨JVM(2-1)ClassLoader的工作机制的更多相关文章

  1. java虚拟机学习-慢慢琢磨JVM(2)

    1 JVM简介 JVM是我们Javaer的最基本功底了,刚开始学Java的时候,一般都是从“Hello World”开始的,然后会写个复杂点class,然后再找一些开源框架,比如Spring,Hibe ...

  2. java虚拟机学习-深入理解JVM(1)

    1   Java技术与Java虚拟机 说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成: Java编程语言.Java类文件格式.Java虚拟机和Java应 ...

  3. java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)

    Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收集(Garbage Collection,下文简称GC),大部分人都把这项 ...

  4. java虚拟机学习-JVM内存管理:深入Java内存区域与OOM(3)

    概述 Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝又 ...

  5. java虚拟机学习-触摸java常量池(13-1)

    java虚拟机学习-深入理解JVM(1) java虚拟机学习-慢慢琢磨JVM(2) java虚拟机学习-慢慢琢磨JVM(2-1)ClassLoader的工作机制 java虚拟机学习-JVM内存管理:深 ...

  6. Java虚拟机学习笔记——JVM垃圾回收机制

    Java虚拟机学习笔记——JVM垃圾回收机制 Java垃圾回收基于虚拟机的自动内存管理机制,我们不需要为每一个对象进行释放内存,不容易发生内存泄漏和内存溢出问题. 但是自动内存管理机制不是万能药,我们 ...

  7. 《深入Java虚拟机学习笔记》- 第19章 方法的调用与返回

    <深入Java虚拟机学习笔记>- 第19章 方法的调用与返回

  8. 《深入Java虚拟机学习笔记》- 第16章 控制流

    <深入Java虚拟机学习笔记>- 第16章 控制流

  9. 《深入Java虚拟机学习笔记》- 第17章 异常

    <深入Java虚拟机学习笔记>- 第17章 异常

随机推荐

  1. WebService基础学习(一)—基础知识

    一.WebService 1.什么是WebService      Web Service(WEB服务)能够快捷和方便地综合结合各种系统.商务和任何应用平台.利用最新的Web Service 标准能够 ...

  2. 【CSS】如何用css做一个爱心

    摘要:HTML的标签都比较简单,入门非常的迅速,但是CSS是一个需要我们深度挖掘的东西,里面的很多样式属性掌握几个常用的便可以实现很好看的效果,下面我便教大家如何用CSS做一个爱心. 前期预备知识: ...

  3. jQuery扩展函数设置所有对象只读

    jQuery(function ($) {             $.fn.disable = function () {                 return this.each(func ...

  4. SQL语句简单整理

    转载原文:http://blog.sina.com.cn/s/blog_48df31d901017c6o.html 1.用户 - 查看当前用户的缺省表空间 select username,defaul ...

  5. Java 原始数据类型

    如何记住 Java 中的原始数据类型? 画了一个图方便记忆:

  6. summerDao-比mybatis更强大无需映射配置的dao工具

    summerDao是summer框架中的一个数据库操作工具,项目地址:http://git.oschina.net/xiwa/summer. 怎么比mybatis更强大,怎么比beetlsql更简单, ...

  7. JS模式---命令模式

    var opendoor = { execute: function () { console.log("开门"); } }; var closedoor = { execute: ...

  8. DirectFB 之 字体显示(2)

    框架 示例代码 /********************************************** * Author: younger.liucn@hotmail.com * File n ...

  9. JS基础部分小结

    [使用js的三种方式] 1.HTML标签中内嵌JS(不提倡使用) 2.HTML页面中直接使用JS <script type="text/javascript"> JS代 ...

  10. Struts2拦截器登录验证

    Struts2拦截器 Struts2拦截器的概念和Spring Mvc拦截器一样. Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截 ...