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类加载器学习笔记
今后一段时间会全面读一下<深入理解Java虚拟机> 在这里先记一下在网上看到的几篇介绍 类加载器 的文章,等读到虚拟机类加载机制再详细介绍. 超详细Java中的ClassLoader详解 ...
- java笔记--理解java类加载器以及ClassLoader类
类加载器概述: java类的加载是由虚拟机来完成的,虚拟机把描述类的Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成能被java虚拟机直接使用的java类型,这就是虚拟机的类加载机制 ...
- Java基础-类加载机制与自定义类Java类加载器(ClassLoader)
Java基础-类加载机制与自定义类Java类加载器(ClassLoader) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 关于类加载器的概念和分类我就不再废话了,因为我在之前的笔 ...
- Java 类加载器及加载Class字节码
参考来源:http://www.cnblogs.com/fingerboy/p/5456371.html java笔记--理解java类加载器以及ClassLoader类 参考来源:htt ...
- java类加载器深入研究
看了下面几篇关于类的加载器的文章,豁然开朗.猛击下面的地址开始看吧. Java类加载原理解析 深入探讨 Java 类加载器 分析BootstrapClassLoader/ExtClassLo ...
- 深入探讨 Java 类加载器
转自:http://www.ibm.com/developerworks/cn/java/j-lo-classloader/ 类加载器(class loader)是 Java™中的一个很重要的概念.类 ...
- JAVA 类加载器 第14节
JAVA 类加载器 第14节 今天我们将类加载机制5个阶段中的第一个阶段,加载,又叫做装载.为了阅读好区分,以下都叫做装载. 装载的第一步就是要获得二进制的字节流,它可以从读.class文件获得,也可 ...
- 深入探讨 Java 类加载器[转]
原文地址:http://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html 类加载器(class loader)是 Java™ ...
- 转载:深入探讨 Java 类加载器
转载地址 : http://www.ibm.com/developerworks/cn/java/j-lo-classloader/ 深入探讨 Java 类加载器 类加载器(class loader) ...
随机推荐
- 安装tcmalloc
安装google-perftools:#tar zxvf google-perftools-1.6.tar.gz #cd google-perftools-1.6 #./configure#make# ...
- Entity Framework - Func引起的数据库全表查询
原文:http://www.cnblogs.com/dudu/archive/2012/04/01/enitity_framework_func.html 使用 Entity Framework 最要 ...
- html5图片标签与属性
标记: 标 记 说 明 <lmg> 图像 <Map> 图像映射 <Area> 图像映射中定义区域 <lmg>标记属性: 属 性 说 明 Src ...
- 九个Console命令,让 JS 调试更简单
一.显示信息的命令 <!DOCTYPE html> <html> <head> <title>常用console命令</title> < ...
- document 例子
<!DOCTYPE html> <html> <head> <title></title> <script type="te ...
- Java ------------获取不会重复的随机数
import java.util.UUID; public class UTest { public static void main(String[] args) { //UUID通过rand ...
- 利用“参数赋值”防范SQL注入漏洞攻击
<<年轻,无权享受>————送给每一个看到此文的同僚们 在这无精打采的炎夏 我躺在阳台上房东的旧沙发 回想几个月来遇到的问题 我不禁内心开始慌张喘着粗气 还有大把时间去打拼 没有到只 ...
- 数据库对象(视图,序列,索引,同义词)【weber出品必属精品】
视图视图的定义:视图就是一个查询的别名为什么使用视图限制数据的存取 SQL> conn /as sysdba 已连接. SQL> grant create view to scott; 授 ...
- MySQL指令记录(Wampserve环境)
1.MySQL在Wampserve中的默认用户名为'root',默认密码为空: 2.显示所有数据库 show databases; 3.切换数据库 use DATABASE_NAME; 4.列出所有表 ...
- 翻译一篇SpiderMonkey GC的文章
前言 这篇文章包含了对SpiderMonkey中Rooted<T>, Handle<T>的解释. 翻译自 https://developer.mozilla.org/en-US ...