快精灵印艺坊 您身边的文印专家
广州名片 深圳名片 会员卡 贵宾卡 印刷 设计教程
产品展示 在线订购 会员中心 产品模板 设计指南 在线编辑
 首页 名片设计   CorelDRAW   Illustrator   AuotoCAD   Painter   其他软件   Photoshop   Fireworks   Flash  

 » 彩色名片
 » PVC卡
 » 彩色磁性卡
 » 彩页/画册
 » 个性印务
 » 彩色不干胶
 » 明信片
   » 明信片
   » 彩色书签
   » 门挂
 » 其他产品与服务
   » 创业锦囊
   » 办公用品
     » 信封、信纸
     » 便签纸、斜面纸砖
     » 无碳复印纸
   » 海报
   » 大篇幅印刷
     » KT板
     » 海报
     » 横幅

Java的ClassLoader与Package机制

为了深入了解Java的ClassLoader机制,我们先来做以下实验:

package java.lang;
public class Test {
public static void main(String[] args) {
char[] c = "1234567890".toCharArray();
String s = new String(0, 10, c);
}
}

String类有一个Package权限的构造函数String(int offset, int length, char[] array),按照默认的访问权限,由于Test属于java.lang包,因此理论上应该可以访问String的这个构造函数。编译通过!执行时结果如下:

Exception in thread "main" java.lang.SecurityException: Prohibited package name:
java.lang
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)

希奇吧?要弄清为什么会有SecurityException,就必须搞清晰ClassLoader的机制。

Java的ClassLoader就是用来动态装载class的,ClassLoader对一个class只会装载一次,JVM使用的ClassLoader一共有4种:

启动类装载器,标准扩展类装载器,类路径装载器和网络类装载器。

这4种ClassLoader的优先级依次从高到低,使用所谓的“双亲委派模型”。确切地说,假如一个网络类装载器被哀求装载一个java.lang.Integer,它会首先把哀求发送给上一级的类路径装载器,假如返回已装载,则网络类装载器将不会装载这个java.lang.Integer,假如上一级的类路径装载器返回未装载,它才会装载java.lang.Integer。

类似的,类路径装载器收到哀求后(无论是直接哀求装载还是下一级的ClassLoader上传的哀求),它也会先把哀求发送到上一级的标准扩展类装载器,这样一层一层上传,于是启动类装载器优先级最高,假如它按照自己的方法找到了java.lang.Integer,则下面的ClassLoader都不能再装载java.lang.Integer,尽管你自己写了一个java.lang.Integer,试图取代核心库的java.lang.Integer是不可能的,因为自己写的这个类根本无法被下层的ClassLoader装载。

再说说Package权限。Java语言规定,在同一个包中的class,假如没有修饰符,默认为Package权限,包内的class都可以访问。但是这还不够正确。确切的说,只有由同一个ClassLoader装载的class才具有以上的Package权限。比如启动类装载器装载了java.lang.String,类路径装载器装载了我们自己写的java.lang.Test,它们不能互相访问对方具有Package权限的方式。这样就阻止了恶意代码访问核心类的Package权限方式。






返回类别: 教程
上一教程: 漫谈Java程序的性能优化
下一教程: 让Java程序自带JRE

您可以阅读与"Java的ClassLoader与Package机制"相关的教程:
· Java的Package与Import机制之我的理解(初学者的心得)
· 学习心得:Java为什么支持反射机制?
· Java中非常机制的深入研究
· Java 理论与实践: JDK 5.0 中更灵活、更具可伸缩性的锁定机制
· "package中的javac,java用法" && "制作可执行jar文件"
    微笑服务 优质保证 索取样品