java类加载机制

ClassLoader 是一个抽象类。为了扩充 [color=red]Java 虚拟机动态装载类的方法[/color],应用程序可实现 ClassLoader 的继承类。

通常,Java 虚拟机以与平台有关的方式,从局部文件系统中装载类。例如,在 UNIX 系统,虚拟机从 CLASSPATH 环境变量中定义的路径中装载类。

但是,

[color=red]某些类可能不是来自文件,而是来自其它资源,诸如网络,或者它们可能是由应用程序创建的。 [/color]

[color=red]defineClass 方法将一字节数组转换为 Class 类的实例。采用 Class 类中的 newInstance 方法创建新定义的类的实例。[/color]

类装载器创建的方法和构造子可以引用其它类。为确定引用类,Java 虚拟机调用初始创建该类的类装载器的 loadClass 方法。如果 Java 虚拟机仅需确定此类是否存在,和如果存在则如何获知它的父类,那么将 resolve 标记设为 false。但是,如果该类的实例已创建,或它的方法已被调用,则必须解析该类。这种情况,resolve 标记设为 true,调用 resolveClass 方法。

例如,一个应用程序能够创建一网络类装载器,从某一个服务器上下载类文件。代码可能如下:

[code]ClassLoader loader = new NetworkClassLoader(host, port);
Object main = loader.loadClass("Main", true).newInstance();
. . . [/code]网络类装载器的子类必须定义 loadClass 方法,实现从网上下载类。一旦已下载完该类,就应使用 defineClass方法,创建它的一个实例。实现示例如下:


[code]class NetworkClassLoader {
String host;
int port;
Hashtable cache = new Hashtable();
private byte loadClassData(String name)[] {
// load the class data from the connection
. . .
}
public synchronized Class loadClass(String name,
boolean resolve) {
Class c = cache.get(name);
if (c == null) {
byte data[] = loadClassData(name);
c = defineClass(data, 0, data.length);
cache.put(name, c);
}
if (resolve)
resolveClass(c);
return c;
}
}[/code]


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都可以访问。但是这还不够准确。

[color=red]确切的说,只有由同一个ClassLoader装载的class才具有以上的Package权限。[/color]

[color=red]比如启动类装载器装载了java.lang.String,类路径装载器装载了我们自己写的java.lang.Test,它们不能互相访问对方具有Package权限的方法。[/color]

这样就阻止了恶意代码访问核心类的Package权限方法。
发布了0 篇原创文章 · 获赞 0 · 访问量 3058
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章