摘自: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...通过类装载器的双亲委托模型,Java能够确保安全地加载和管理类,而命名空间则提供了有序且无冲突的类组织方式。理解这些概念对于深入学习Java和进行高级Java编程至关重要。
2. **安全性**:类装载器确保只有经过验证的类才能被加载到JVM中。这样可以防止恶意代码的注入,从而提高了应用程序的安全性。 3. **隔离性**:不同的类装载器可以加载相同的类文件,但是这些类在JVM中被认为是不同...
1. **类装载器的层次结构**:Java的类装载器采用双亲委派模型,即当一个类装载器接到加载类的请求时,它首先会委托父类装载器去尝试加载,只有当父类装载器无法加载时,子类装载器才会尝试自己加载。这种模型保证了...
在开发过程中,你需要注意类装载器的双亲委托模型,这是一种安全机制,确保核心类库不会被非法替换,避免类的冲突。 编写自定义类装载器时,你可能会遇到的问题包括类的加载顺序、类的可见性、类的唯一性以及如何...
校验会检查二进制数据的正确性和安全性,准备阶段为类的静态变量分配内存并初始化,解析则是将符号引用转换为直接引用,以便后续的直接访问。最后的初始化阶段,会执行类的静态初始化代码块和静态变量的初始化。 在...
Java类装载器的体系结构基于委托模型。当JVM请求加载一个类时,装载器首先将请求传递给其父装载器。只有当父装载器无法加载该类时,当前装载器才会尝试加载。这种结构形成了一个树形层次,根装载器(Bootstrap ...
类装载器学习一、类加载器的基本概念 类装载器学习一、类加载器的基本概念 类装载器学习一、类加载器的基本概念
3. **TYRE15.SLDPRT**:轮胎是装载机的行走装置,模型中包含了装载机的轮胎设计,考虑了承载能力、行驶稳定性以及地面抓地力等因素,确保设备在各种工况下的正常运行。 4. **JANT14.SLDPRT**:这部分可能指的是装载...
在Java中,类装载器是分层的,由Bootstrap ClassLoader、Extension ClassLoader和App ClassLoader构成,它们遵循双亲委托模型。当一个类装载器收到加载类的请求时,它首先会委托给父类装载器,只有当父类装载器无法...
3. "22.sub assemply light.SLDASM":可能是装载机的照明系统或部分结构的装配,对于设备在夜间或低光照环境下的操作安全性具有重要意义。 4. "21.tire.SLDPRT":单独的轮胎零件模型,用户可以单独查看轮胎的细节,...
Java的类加载机制遵循双亲委派模型,即当一个类加载器收到加载类的请求时,它首先会委托父类加载器去尝试加载,只有当父类加载器无法加载时,当前类加载器才会尝试自己加载。这种模型保证了Java核心库类的一致性和...
而在动画制作中,模型会被赋予骨骼和动画控制器,使得装载机可以执行各种动作,如铲土、转向、提升等。 压缩包内的文件"三维模型"可能是多个文件的集合,包括但不限于以下几种: 1. 3D模型文件:如".max"(3ds Max...
从Java 1.2版本开始,引入了一种称为“双亲委派”(Parent Delegation)的模型,这种模型的主要目的是提高Java平台的安全性。该模型的工作原理如下: - 当一个类装载器接收到加载类的请求时,它首先会委托给自己的...
3. **改变WAR类装载器的委托模式**:探讨了如何通过修改WAR文件的类装载器委托模式来优化类的查找过程。 4. **使用共享库共享工具JAR**:介绍了如何利用共享库特性来避免多个应用之间重复加载相同的JAR文件。 通过...
### 利用类装载器动态加载类并启动类 #### 概述 本文将详细介绍如何通过自定义类装载器来动态加载并启动类的过程,同时介绍一个简单的位移...这种方式不仅增强了数据的安全性,也为动态加载类提供了灵活的解决方案。
包括引导类装载器(Bootstrap ClassLoader)、扩展类装载器(Extension ClassLoader)和应用程序类装载器(Application ClassLoader),它们共同构成了双亲委派模型,保证了类装载的有序性和安全性。当一个类被装载...
类装载器的设计考虑到了多个层面的安全性问题: - **命名空间与运行时包**:类装载器为每个加载的类提供了独立的命名空间,从而避免了恶意代码干扰正常运行的代码。同一命名空间下的类可以互相访问,而不同命名空间...
文档中介绍的技术实现表明,Android的类装载器架构为开发者提供了丰富的可能性,使得在保证应用安全性的同时,也能够灵活地进行插件化开发。通过运用PathClassLoader和DexClassLoader,开发者可以设计出更加灵活和...
Java类加载器分为系统类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用程序类加载器(AppClassLoader),它们遵循双亲委派模型。当一个类需要被装载时,加载请求会首先传递给顶级的...