摘自:http://blog.csdn.net/yuan22003/article/details/6839335
一. 基本概念
类加载器是用来把类 class 装载入 JVM 的
Java 运行时会产生三个 ClassLoader
Bootstrap ClassLoader(C++ 编写 ) 用来加载核心类库(lib目录下的jar包),如 java.lang.* 等
↑
ExtClassLoader 用来加载 lib/ext 目录下或者 ext.dir 指定的目录下的类库。
↑
AppClassLoader 用来加载 CLASSPATH 下的类库及类
其中,ExtClassLoader和AppClassLoader也是由Bootstrap ClassLoader加载的。我们也可以继承ClassLoader,实现自己的ClassLoader
二. 双亲委托模型
更好的保证 JAVA 平台的安全。在此模型下,当一个装载器被请求加载某个类时,先委托自己的 parent 去装载,如果 parent 能装载,则返回这个类对应的 Class 对象,否则,递归委托给父类的父类装载。
在此模型下,用户自定义的类装载器,不可能装载应该由父亲装载的可靠类,从而防止不可靠甚至恶意的代码代替本应该由父亲装载器装载的可靠代码。
三. 命名空间
假设我们有如下结构:
Loader1( 装载 Class1)
↑
Loader2 ( 装载 Class2)
↑ ↑
Loader3( 装载 Class3) Loader4( 装载 Class4)
其中, Loader1 实际装载了 Class1 , Loader 实际装载了 Class2 ,其余类似。
这里我们明确 2 个概念:
定义类装载器 :实际装载类的类装载器。比如上例中的 Class1 的定义类装载器就是 Loader1 。 Class3 的定义类装载器就是 Loader3 。
初始类装载器: 任何被要求装载某个类型,并且能够返回该类型的 Class 的类装载器,都称为改类型的初始类装载器。比如上例中, Class1 的初始装载器有 Loader3,Loader4,Loader2,Loader1 。 所以,从定义类装载器往下的所有子装载器,都是该类型的初始类装载器,包括定义类装载器。
每个 ClassLoader 都有自己的命名空间,命名空间由所有以此装载器为初始类装载器的类组成,见下表:
类加载器 |
命名空间 |
Loader1 |
Class1 |
Loader2 |
Class1 Class2 |
Loader3 |
Class1 Class2 Class3 |
Loader4 |
Class1 Class2 Class4 |
ClassLoader 在调用 loadClass 之前,总会先检查当前的命名空间(内部列表),如果 ClassLoader 是这个类型的初始类装载器,就会返回表示这个类型的 Class 实例。这样,虚拟机永远不会在同一个 ClassLoader 上装载同一个类型 2 次。
不同命名空间的两个类是不可见的 (如,上例中的 Class3 和 Class4 ) ,但只要得到类所对应的Class对象的reference,还是可以访问另一命名空间的类。
四. 运行时包
由同一个 ClassLoader 定义装载的属于相同包的类,组成了运行时包,决定两个类是不是属于同一个运行时包,不仅要看包名是否相同,还要看是否是由同一个 ClassLoader 加载的。 只有属于同一个运行时包的类才能互相访问包可见的类和成员。
这样的限制避免了用户自己的代码冒充核心类库的类访问核心类库包可见成员的情况。假设用户自己定义了一个类 java.lang.xxx ,并用自定义的 ClassLoader 装载,由于 Java.lang.* 和 java.lang.xxx 是由不同的装载器装载,属于不同的运行时包,所以 java.lang.xxx 不能访问核心类库 java.lang 中类的包可见成员。
综上,命名空间隔并不完全禁止属于不同空间的类的互相访问,而双亲委托加强了 Java 的安全,运行时包增加了对包可见成员的保护。
五. 实现自己的ClassLoader
我们也可以实现自己的ClassLoader,通过继承ClassLoader类,并重写findClass方法。例:
- import java.io.ByteArrayOutputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- public class MyClassLoader extends ClassLoader {
- public Class findClass(String name) {
- byte[] data = loadClassData(name);
- return defineClass(name, data, 0, data.length);
- }
- public byte[] loadClassData(String name) {
- FileInputStream fis = null;
- byte[] data = null;
- try {
- fis = new FileInputStream(new File("E:/home/" + name.replace(".", "/") + ".class"));
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- int ch = 0;
- while ((ch = fis.read()) != -1) {
- out.write(ch);
- }
- data = out.toByteArray();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return data;
- }
- }
相关推荐
主要讲述Java的类装载器和命名空间,ClassLoader/parent delegation模型
类装载器学习一、类加载器的基本概念 类装载器学习一、类加载器的基本概念 类装载器学习一、类加载器的基本概念
装载机三维模型
类装载器是Java 平台上最神秘,也是最 有趣的一个组,通过类装载器,除了可以实现程序的动态性之外,更能够做 到 无 懈 可 击 的 安 全 性
装载机叉车三维模型
利用类装载器动态加载类并启动类,进行对文件的加密和解密
java jvm类装载器原理 介绍较为详细 大家可以参考
对于问题三,我们首先分析了成件包装货物的种类,将成件包装货物分为长方体货物和非长方体货物两大类,然后运用与问题一相似的优化思想及其方法,构建出规格不统一情况下,棚车最优装载方案的数学模型。 关键词: ...
类装载器ClassLoader1
链接器和装载器linkers_and_loaders 中英文双版
java类装载介绍,介绍了java装载类的先后顺序
装载机叉车三维模型
深入JVM内核—原理、诊断与优化视频教程-6. 类装载器 深入JVM内核—原理、诊断与优化视频教程-6. 类装载器
Android基于类装载器插件架构的实现.pdf
它以提高物流主体作业“运送”、“保管”的装载效率,以削减物流成本为目的,通过最优化装载分析过程,在物流企业不发生实际货物物理转移的情况下,综合考虑货物形状、装载安全性、空间利用率等因素,利用计算机做...
java之jvm学习笔记五(实践写自己的类装载器)
类装载器
[浅析J2EE应用服务器的JAVA类装载器]python回朔异常的模块.docx
Java虚拟机类装载111.docJava虚拟机类装载111.docJava虚拟机类装载111.doc
类的动态装载机制是JVM的一...本文介绍了JVM中类装载的原理、实现以及应用,尤其分析了ClassLoader的结构、用途以及如何利用自定义 的ClassLoader装载并执行Java类,希望能使读者对JVM中的类装载有一个比较深入的理解。