- 浏览: 531046 次
- 性别:
- 来自: 西安
文章分类
- 全部博客 (233)
- 设计模式 (1)
- WEBLOGIC (2)
- spring (2)
- struts (1)
- hibernate (8)
- SOA (11)
- j2ee (0)
- corba (0)
- linux (2)
- oracle (0)
- webService (17)
- javaMail (1)
- junit (3)
- java (45)
- 正则表达式 (7)
- java+xml (4)
- html (2)
- javaScript (6)
- ajax (1)
- mysql (0)
- eclipse (2)
- eclipse插件开发 (3)
- 软件工程 (5)
- ant (6)
- 开源包 (6)
- 学习网站 (7)
- Struts2 (18)
- JSP (1)
- 持续集成 (4)
- FreeMaker (6)
- 工作项目点点 (4)
- Maven2 (6)
- JQuery (1)
- 日志记录 (9)
- 工作流 (4)
- BPEL (1)
- extJs (1)
- 组件 (1)
- OSGI (10)
- ESB总线学习 (1)
- 错误解决 (2)
- JMX (3)
- 网络知识 (1)
最新评论
-
duanlongk:
这个问题解决了么?
java.lang.NoClassDefFoundError: org/apache/tuscany -
sotrip:
从上面结果来看,HelloWorld.class是由虚拟机的内 ...
如何实现自己的classloader -
zengsir2008:
哎,不太明白。。。。
OSGI DS 实例 -
ralfsumahe:
...
使用XFire开发Web Service客户端完整入门教程 -
liuqiao_0702:
...
osgi spring hibernate =
Java的类装载器(Class Loader)和命名空间(NameSpace)
摘要
Java的类装载器是Java动态性的核心,本文将向大家简要介绍Java的类装载器,及相关的parent delegation模型,命名空间,运行时包等概念,同时讨论一些在学习中容易混淆的问题。
类装载器的功能及分类
顾名思义,类装载器是用来把类(class)装载进JVM的。JVM规范定义了两种类型的类装载器:启动内装载器(bootstrap)和用户自定义装载器(user-defined class loader)。
bootstrap是JVM自带的类装载器,用来装载核心类库,如java.lang.*等。由例1可以看出,java.lang.Object是由bootstrap装载的。
Java提供了抽象类ClassLoader,所有用户自定义类装载器都实例化自ClassLoader的子类。 System Class Loader是一个特殊的用户自定义类装载器,由JVM的实现者提供,在编程者不特别指定装载器的情况下默认装载用户类。系统类装载器可以通过ClassLoader.getSystemClassLoader() 方法得到。
例1,测试你所使用的JVM的ClassLoader
/*LoaderSample1.java*/ public class LoaderSample1 { public static void main(String[] args) { Class c; ClassLoader cl;
cl = ClassLoader.getSystemClassLoader(); System.out.println(cl);
while (cl != null) { cl = cl.getParent(); System.out.println(cl); } try { c = Class.forName("java.lang.Object"); cl = c.getClassLoader(); System.out.println("java.lang.Object's loader is " + cl); c = Class.forName("LoaderSample1"); cl = c.getClassLoader(); System.out.println("LoaderSample1's loader is " + cl); } catch (Exception e) { e.printStackTrace(); } } }
在我的机器上(Sun Java 1.4.2)的运行结果
sun.misc.Launcher$AppClassLoader@1a0c10f sun.misc.Launcher$ExtClassLoader@e2eec8 null java.lang.Object's loader is null LoaderSample1's loader is sun.misc.Launcher$AppClassLoader@1a0c10f
第一行表示,系统类装载器实例化自类sun.misc.Launcher$AppClassLoader
第二行表示,系统类装载器的parent实例化自类sun.misc.Launcher$ExtClassLoader
第三行表示,系统类装载器parent的parent为bootstrap
第四行表示,核心类java.lang.Object是由bootstrap装载的
第五行表示,用户类LoaderSample1是由系统类装载器装载的
parent delegation模型
从1.2版本开始,Java引入了双亲委托模型,从而更好的保证Java平台的安全。在此模型下,当一个装载器被请求装载某个类时,它首先委托自己的parent去装载,若parent能装载,则返回这个类所对应的Class对象,若parent不能装载,则由parent的请求者去装载。
如图1所示,loader2的parent为loader1,loader1的parent为system class loader。假设loader2被要求装载类MyClass,在parent delegation模型下,loader2首先请求loader1代为装载,loader1再请求系统类装载器去装载MyClass。若系统装载器能成功装载,则将MyClass所对应的Class对象的reference返回给loader1,loader1再将reference返回给loader2,从而成功将类MyClass装载进虚拟机。若系统类装载器不能装载MyClass,loader1会尝试装载MyClass,若loader1也不能成功装载,loader2会尝试装载。若所有的parent及loader2本身都不能装载,则装载失败。
若有一个能成功装载,实际装载的类装载器被称为定义类装载器,所有能成功返回Class对象的装载器(包括定义类装载器)被称为初始类装载器。如图1所示,假设loader1实际装载了MyClass,则loader1为MyClass的定义类装载器,loader2和loader1为MyClass的初始类装载器。
图 1 parent delegation模型
需要指出的是,Class Loader是对象,它的父子关系和类的父子关系没有任何关系。一对父子loader可能实例化自同一个Class,也可能不是,甚至父loader实例化自子类,子loader实例化自父类。假设MyClassLoader继承自ParentClassLoader,我们可以有如下父子loader:
ClassLoader loader1 = new MyClassLoader(); //参数 loader1 为 parent ClassLoader loader2 = new ParentClassLoader(loader1);
那么parent delegation模型为什么更安全了?因为在此模型下用户自定义的类装载器不可能装载应该由父亲装载器装载的可靠类,从而防止不可靠甚至恶意的代码代替由父亲装载器装载的可靠代码。实际上,类装载器的编写者可以自由选择不用把请求委托给parent,但正如上所说,会带来安全的问题。
命名空间及其作用
每个类装载器有自己的命名空间,命名空间由所有以此装载器为创始类装载器的类组成。不同命名空间的两个类是不可见的,但只要得到类所对应的Class对象的reference,还是可以访问另一命名空间的类。
例2演示了一个命名空间的类如何使用另一命名空间的类。在例子中,LoaderSample2由系统类装载器装载,LoaderSample3由自定义的装载器loader负责装载,两个类不在同一命名空间,但LoaderSample2得到了LoaderSample3所对应的Class对象的reference,所以它可以访问LoaderSampl3中公共的成员(如age)。
例2不同命名空间的类的访问
/*LoaderSample2.java*/ import java.net.*; import java.lang.reflect.*; public class LoaderSample2 { public static void main(String[] args) { try { String path = System.getProperty("user.dir"); URL[] us = {new URL("file://" + path + "/sub/")}; ClassLoader loader = new URLClassLoader(us); Class c = loader.loadClass("LoaderSample3"); Object o = c.newInstance(); Field f = c.getField("age"); int age = f.getInt(o); System.out.println("age is " + age); } catch (Exception e) { e.printStackTrace(); } }
}
/*sub/Loadersample3.java*/ public class LoaderSample3 { static { System.out.println("LoaderSample3 loaded"); } public int age = 30; }
编译:javac LoaderSample2.java; javac sub/LoaderSample3.java
运行:java LoaderSample2
LoaderSample3 loaded age is 30
从运行结果中可以看出,在类LoaderSample2中可以创建处于另一命名空间的类LoaderSample3中的对象并可以访问其公共成员age。
运行时包(runtime package)
由同一类装载器定义装载的属于相同包的类组成了运行时包,决定两个类是不是属于同一个运行时包,不仅要看它们的包名是否相同,还要看的定义类装载器是否相同。只有属于同一运行时包的类才能互相访问包可见的类和成员。这样的限制避免了用户自己的代码冒充核心类库的类访问核心类库包可见成员的情况。假设用户自己定义了一个类java.lang.Yes,并用用户自定义的类装载器装载,由于java.lang.Yes和核心类库java.lang.*由不同的装载器装载,它们属于不同的运行时包,所以java.lang.Yes不能访问核心类库java.lang中类的包可见的成员。
总结
在简单讨论了类装载器,parent delegation模型,命名空间,运行时包后,相信大家已经对它们的作用有了一定的了解。命名空间并没有完全禁止属于不同空间的类的互相访问,双亲委托模型加强了Java的安全,运行时包增加了对包可见成员的保护。
发表评论
-
类加载机制转载
2009-06-23 09:58 2340Java中一共有四个类加载器,之所以叫类加载器,是程序要用到某 ... -
OSGI环境下配置log4j日志
2009-05-07 14:07 1403log4j相信大家都用过的 ... -
Java虚拟机类装载:原理、实现与应用
2009-05-07 09:50 1491Java虚拟机类装载:原理、实现与应用 By jo ... -
Java程序类加载完全揭密
2009-05-07 09:49 1074Java程序类加载完全揭密 ... -
Java类装载体系中的隔离性
2009-05-07 09:28 1400Java类装载体系中的隔离性 正文 Java中类 ... -
了解 JAVA classloader
2009-05-07 09:21 1066什么是 ClassLoader? ... -
如何实现自己的classloader
2009-05-07 09:12 2023如何实现自己的classloader 如何实现自己的clas ... -
ClassLoader原理
2009-05-07 09:06 1003JVM规范定义了两种类型的类装载器:启动内装载器(bootst ... -
JDK1.5中的线程池(java.util.concurrent.ThreadPoolExecuto
2009-04-03 11:32 1290在多线程大师Doug Lea的 ... -
MD5
2009-03-17 09:17 1003使用 Java 生成 MD5 编码 MD5即 ... -
JAVA字符串处理函数列表一览
2009-03-14 16:48 2009Java中的字符串也是一连串的字符。但是与许多其他的计算机语言 ... -
StringTokenizer(字符串分析解析类型)(转)
2009-03-14 16:35 3109功效:将字符串以定界符为界,分析为一个个的token(可理解为 ... -
JAVA乱码分析
2009-03-14 16:33 2148UNICODE编码,它采用双字 ... -
java.util.UUID
2008-12-19 18:01 4935GUID是一个128位长的数字,一般用16进制表示。算法的核心 ... -
java应用程序中动态生成PDF文件
2008-12-11 17:05 1164很多应用程序要求动态 ... -
JAVA和JAVAC 命令行
2008-12-11 17:03 2579javac和java命令行中的-classpath选项这是个很 ... -
创建java的可执行文件
2008-12-11 16:59 1368Jar工具的作用是java程序中若干文件联合压缩到一个Jar包 ... -
深入对象复制与比较
2008-12-04 10:09 15061.对象的复制2.clone()的使用3.对象实例的比较/// ... -
解析Java对象的equals()和hashCode()的使用
2008-12-04 10:07 846在Java语言中,equals()和h ... -
Java基础:深入 JAVA对象的复制与比较
2008-12-04 10:06 8571.对象的复制2.clone()的使用3.对象实例的比较/// ...
相关推荐
主要讲述Java的类装载器和命名空间,ClassLoader/parent delegation模型
类装载器学习一、类加载器的基本概念 类装载器学习一、类加载器的基本概念 类装载器学习一、类加载器的基本概念
java类装载介绍,介绍了java装载类的先后顺序
类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一。它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java ...
[浅析J2EE应用服务器的JAVA类装载器]python回朔异常的模块.docx
类装载器是Java 平台上最神秘,也是最 有趣的一个组,通过类装载器,除了可以实现程序的动态性之外,更能够做 到 无 懈 可 击 的 安 全 性
Android 3.0装载器 Loader
Java虚拟机类装载的原理及实现
Java类装载过程_.docx
Java虚拟机类装载111.docJava虚拟机类装载111.docJava虚拟机类装载111.doc
类的动态装载机制是JVM的一...本文介绍了JVM中类装载的原理、实现以及应用,尤其分析了ClassLoader的结构、用途以及如何利用自定义 的ClassLoader装载并执行Java类,希望能使读者对JVM中的类装载有一个比较深入的理解。
java jvm类装载器原理 介绍较为详细 大家可以参考
简单的介绍和描述Java虚拟机类装载:原理、实现与应用
本例采用java编写的装载问题,采用的是FIFO队列形式,参考:算法设计与分析
摘要通过构建一个能够把Java类装载隔离到一个指定的jar文件中的类装载组件容器框架,你可以确保运行时刻会装载你期望的组件版本。Java的类装载框架强有力且具有灵活性。它允许应用程序存取类库而不必链接到静态的...
classguard是防止java反编译工具的工具,它允许java类文件使用128bit的AES加密加密。AES密钥是随机生成的每次启动加密工具。解密是一个自定义的类装载器透明地做。这类装载器的主要部分是用C防止反编译等篡改。
利用类装载器动态加载类并启动类,进行对文件的加密和解密
java虚拟机装载类的原理,从基础上描述,让我们更清楚底层的运作
java之jvm学习笔记五(实践写自己的类装载器)
海量数据装载工具SQL Loader技术分析.pdf