1. Java虚拟机使用第一个类的第一件事情就是将该类的字节码装进来,装载类字节码的功能是由类装器完成的,类半遮器负责根据一个类的名称来定位和生成类的字节码数据后返回给Java虚拟机。
2. 类装载器本身也是一个Java类,Java虚拟机也允许开发人员编写自己的类装载器,以便通过其他种特殊方式来产生类字节码。
3. 不管类装载器采用什么方式,只要能够在内存中制造出给Java虚拟调用的类字节码即可,所以,把类装载器描述为类字节的制造器更容易让人理解。
4. 当一个类被加载后,Java虚拟机将其编译为可执行代码并存储在内存,并将索引信息存储进一个Hashtable中,其索引关键字为与之相对应的类名。
5. Java类库中提供了一个java.lang.ClassLoader来作为类装载器的基类,Java虚拟机和程序都调用ClassLoader类的loadClass方法来加载类,ClassLoader是一个抽象类,真正的类装载器必须是ClassLoader类的子类。
6. Class类中定义了一个getClassLoader方法,用于返回它所描述的类的类加载器对象,这个返回对象的类型就是ClassLoader。
类装载器的基本策略
1. 一个类装载器本身也是一个Java类,所以,类装载器自身也需要被另外一个类装载器装载。
2. Java虚拟机中内嵌了一个称为Bootstrap的类装载器,它属于Java虚拟机的内核,不用类装载器装载。Bootstrap类装载器负责加载Java核心包中的类(即rt.jar文件中的类),这些类的Class.getClassLoader方法返回值为null,即表示是Bootstrap类装载器。
3.ExtClassLoader类装载器负责加载存放在<JAVA_HOME>/jre/lib/ext目录下的jar包中的类,AppClassLoader负责加载应用程序的启动执行类,即含有main方法的类,AppClassLoader是应用程序的第一个类装载器。


类装载器的委托模式
1. 一个Java虚拟机中的所有类装载器采用具有父子关系的树形结构进行组织,在实例化每个类装载器对象时,需要为其指定一个父级类装载器对象,如果没有指定的话则以ClassLoader.getSystemClassLoader()方法返回的系统类装载器作为其父级类装载器对象。
2. 系统类装载器通常被设置为启动应用程序的AppClassLoader,可以通过java.system.class.loader系统属性将系统类装载器设置为其它类装载器。ExtClassLoader是AppClassLoader的父级类装载器,ExtClassLoader没有父级类装载器,其实ExtClassLoader的父级类装载器是Bootstrap类装载器,但因Bootstrap不是一个Java类,它是Java虚拟机的内核,所以就干脆说ExtClassLoader没有父级类装载器。
3. 每个ClassLoader本身只能分别加载特定位置和目录中的类,但是,ClassLoader被设计成了一种委托模式,使得某一个ClassLoader可以委托它的父级类装载器去加载类,从而让应用程序可以借助某一个子级的ClassLoader去多个位置和目录中进行类的加载。
4. 当要加载一个类时,CLassLoader的loadClass方法先查找这个类是否已被装载,如果没有加载则委托其父级类装载器去加载这个类,如果父级类装载器无法装载这个类,子级类装载器才调用自己内容的findClass方法去真正加载。委托过程会一直坐收追溯到Bootstrap类装载器,如果Bootstrap类装载器也不能加载到类的话就会退回给子级类装载器直到发启装载的那个类装载器。如果委托过程中的所有类装载器都不能完成类的装载,最终就会报告ClassNotFoundException异常。
5. 一个类装载器只能创建某个类的一份字节码数据,即只能为某个类创建一个与之对应的Class实例对象。在一个Java虚拟机中可以存在多个类加载器,第个类加载器都拥有自己的名称空间,对于同一个类,每个类加载器都可以创建出它的一个Class实例对象。如果两个加载器加载了同一个类,就会实例化出了两个这个类的实例,但这个实例对象没有任何关系。
6. 采用委托模式避免了一个Java虚拟机中的多个类装载器为同一个类创建多份字节码数据的情况。只要开发人员自定义的类装载器不覆盖ClassLoader的loadClass方法,而是覆盖其findClass方法,这样就可以继续采用委托模式。因为loadClass方法所做的操作只是说去委托给其父装载器进行类的加载,findClass方法才是进行加装.class文件的加载操作,当父级装载器不能装载的情况下就会调用自己的findClass方法去加载字节码数据。


线程中的类装载器
1. 如果在类A中使用new关键字创建类B,Java虚拟机将使用加载类A的装载器来加载类B。如果在一个类中调用Class.forName方法来动态加载另外一个类,可以通过传递Class.forName方法的一个参数来指定另外那个类的类装载器,如果没有指定该参数,则使用加载当前类的类装载器。
2. 依据一个类的存放位置,这个类最终只能由一个特定的类装载器装载。对于一个已被父级类装载器装载的类来说,Java虚拟机默认也使用这个父级类装载器去装载它所调用的其他类,由于父级类装载器不会委托子级类装载器去装载类,所以在一般情况下,一个已被父级类装载器装载的类无法调用那些只能被子级类装载器去发现和装载的其他类。
3. 每个运行后线程都有一个关联的上下文类装载器,可以使用Thread.setContextClassLoader()方法设置线程的上下文类装载器。
4. 子线程默认的上下文类装载器是父线程的上下文类装载器,而主线程的类装载器初始被设置为ClassLoader.getSystemClassLoader()方法返回的系统类加载器。
5. 当线程中运行的代码需要使用某个类时,它使用上下文类装载器来装载这个类,上下文类装载器首先会委托它的父级类装载器来装载这个类,如果父级类装载器无法装载时,上下文类装载器才自己进行装载。


Tomcat5中的类加载器

Tomcat中的线程上下文类装载器为它们各自的Webbap类装载器。
1. Bootstrap为Java虚拟机内嵌的类装载器与ExtClassLoader的总称,负责加载Java核心包中的类和存放在<JAVA_HOME>/jre/lib/ext目录下的jar包中的类。
2.System即系统类装载器,通常情况下就是AppClassLoader,负责加载CLASSPATH环境变量设置的目录中的类。Tomcat不会继承操作系统上原来设置好的CLASSPATH环境变量的内容,而是将CLASSPATH环境变量重新设置为仅包含如下两个jar包:
<CATALINA_HOME>/bin/bootstrap.jar
<JAVA_HOME>/lib/tools.jar
3. Common类装载器负责从<CATALINA_HOME>/common/classes中的.class类文件和<CATALINA_HOME>/common/lib中的jar包加载类。
4. Catalina类装载器负责从<CATALINA_HOME>/server/classes中的.class类文件和<CATALINA_HOME>/server/lib中的jar包加载类
5.Shared类装载器负责从<CATALINA_HOME>/share/classes中的.class类文件和<CATALINA_HOME>/share/lib中的jar包加载类。
6.WebappX类装载器负责从当前Web应用程序的/WEB-INF/classes中的.class类文件和/WEB-INF/lib中的jar包中加载类。

Tomcat6中的类加载器与Tomcat5有了一些变化,少了一些类加载器,下面是Tomcat6中的类加载器树状图:

少了catalina与shared类加载器,从Tomcat6中的目录结构也可以看出到,6中已经没有shared,common,server文件夹了,至少Tomcat6中这些类加载器具体加载哪些jar,可参看Tomcat6的docs。

java类加载器行为[笔记]的更多相关文章

  1. Java类加载器学习笔记

    今后一段时间会全面读一下<深入理解Java虚拟机> 在这里先记一下在网上看到的几篇介绍 类加载器 的文章,等读到虚拟机类加载机制再详细介绍. 超详细Java中的ClassLoader详解 ...

  2. java笔记--理解java类加载器以及ClassLoader类

    类加载器概述: java类的加载是由虚拟机来完成的,虚拟机把描述类的Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成能被java虚拟机直接使用的java类型,这就是虚拟机的类加载机制 ...

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

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

  4. Java 类加载器及加载Class字节码

    参考来源:http://www.cnblogs.com/fingerboy/p/5456371.html       java笔记--理解java类加载器以及ClassLoader类 参考来源:htt ...

  5. java类加载器深入研究

    看了下面几篇关于类的加载器的文章,豁然开朗.猛击下面的地址开始看吧. Java类加载原理解析      深入探讨 Java 类加载器 分析BootstrapClassLoader/ExtClassLo ...

  6. 深入探讨 Java 类加载器

    转自:http://www.ibm.com/developerworks/cn/java/j-lo-classloader/ 类加载器(class loader)是 Java™中的一个很重要的概念.类 ...

  7. JAVA 类加载器 第14节

    JAVA 类加载器 第14节 今天我们将类加载机制5个阶段中的第一个阶段,加载,又叫做装载.为了阅读好区分,以下都叫做装载. 装载的第一步就是要获得二进制的字节流,它可以从读.class文件获得,也可 ...

  8. 深入探讨 Java 类加载器[转]

    原文地址:http://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html 类加载器(class loader)是 Java™ ...

  9. 转载:深入探讨 Java 类加载器

    转载地址 : http://www.ibm.com/developerworks/cn/java/j-lo-classloader/ 深入探讨 Java 类加载器 类加载器(class loader) ...

随机推荐

  1. EBS-PAC成本更新事务处理

     PAC成本更新事务处理 DECLARE   l_itfs_rec mtl_transactions_interface% ROWTYPE; BEGIN   --插入接口表   SELECT mt ...

  2. Citrix 服务器虚拟化之十 Xenserver高可用性HA

    Citrix 服务器虚拟化之十 Xenserver高可用性HA HA是一套全自动功能设计,规划.它可以安全地恢复出现问题的XenServe 主机.例如物理破坏网络或主机的硬件故障,HA可确保无需任何人 ...

  3. [转载]aptitude与apt-get的区别和联系

    转自 http://www.cnblogs.com/yuxc/archive/2012/08/02/2620003.html 命令 下面将要介绍的所有命令都需要sudo!使用时请将“packagena ...

  4. Stm32高级定时器(四)

    Stm32高级定时器(四) 1 编码器接口模式 1.1 编码器原理 什么是正交?如果两个信号相位相差90度,则这两个信号称为正交.由于两个信号相差90度,因此可以根据两个信号哪个先哪个后来判断方向.根 ...

  5. .NET基础拾遗(3)字符串、集合和流2

    二.常用集合和泛型 2.1 int[]是值类型还是引用类型? .NET中无论是存储值类型对象的数组还是存储引用类型的数组,其本身都是引用类型,其内存也都是分配在堆上的.所有的数组类型都继承自Syste ...

  6. asp.net mvc 页面缓存

    在任务中需要实现点击浏览器back按钮,加载的前一页面需要强制刷新. 想要在前端通过js来绑定数据实现,但是觉得太麻烦,还是用另一种方式来解决: 不缓存该页面. 简单易懂: Response.Cach ...

  7. www

    dddd int vec_rotate(char *vec,int rotdist, int length) { int i,j,k,times; char t; times = gcd(rotdis ...

  8. dwz笔记之tree权限扩展

    碰到的问题:tree选择子节点时,父级节点的值没有选择 解决方法如下(红色部分): 原代码: _checkParent:function(){ if($(this).parent().hasClass ...

  9. 字符串:各种奇葩的内置方法 - 零基础入门学习Python014

    字符串:各种奇葩的内置方法 让编程改变世界 Change the world by program 字符串:各种奇葩的内置方法 或许现在又回过头来谈字符串,有些朋友可能会觉得没必要,也有些朋友会觉得不 ...

  10. 我和小美的撸码日记--基于MVC+Jqgrid的.Net快速开发框架

    前言:以前的帐号没有发首页的权限,特此把这篇文章从另外一个博客移过来,这篇是<我和小美的撸码日记>的序 一转眼务农6年了,呆过大公司也去过小作坊,码农的人生除了抠腚还是抠腚.在所有呆过的公 ...