谈谈Java虚拟机3――动态扩展 (一)

2014-11-24 03:19:45 · 作者: · 浏览: 4

Java的体系结构允许动态扩展Java程序,这个过程包括运行时决定所使用的类型,装载它们,使用它们。通过传递类型的名字到java.lang.Class的forName()方法,或者用户自定义的类装载器的loadClass()方法,可以动态扩展Java程序。两种方法都可以使运行中的程序去调用在源代码中未曾提及的,而是在程序运行中决定的类型。动态扩展的例子如支持Java的Web浏览器,它跨网络装载applet的class文件。当浏览器启动的时候,它不知道将要从网络上装载什么class文件,当它遇到包含这些applet的网页的时候才知道每个applet所需的类和接口的名字。

动态扩展Java程序最直接的方式就是使用java.lang.Class的forName()方法,它有两种重载形式。

public static Class< > forName(String className)

throws ClassNotFoundException {

return forName0(className, true, ClassLoader.getCallerClassLoader());

}

public static Class< > forName(String name, boolean initialize,

ClassLoader loader)

throws ClassNotFoundException

{

if (loader == null) {

SecurityManager sm = System.getSecurityManager();

if (sm != null) {

ClassLoader ccl = ClassLoader.getCallerClassLoader();

if (ccl != null) {

sm.checkPermission(

SecurityConstants.GET_CLASSLOADER_PERMISSION);

}

}

}

return forName0(name, initialize, loader);

}

forName()的三参数形式是在1.2版中加入的,将类型的全限定名装入String类型的className参数。如果boolean类型的initialize参数为true,类型会在forName()方法返回之前连接并初使始化;如果initialize参数为false,类型会被装载,可能会被连接但是不会被forName()方法明确地初始化。然而,如果该类型在调用forName()之前已经被初始化了,即使将false作为第二个参数传递到forName(),返回的类型也已经被初始化了。第三个参数为ClassLoader,传递一个用户定制的类装载器的引用给forName(),让其使用这个类装载器来请求类型。也可以指定forName()用默认的启动类装载器来请求类型,只需传递null作为ClassLoader参数。forName()还有一个只采用一个参数的版本,它总是使用当前的类装载器(就是装载执行forName()请求的类的类装载器),并且总是初始化该类型。两个版本的forName()方法都返回Class实例的引用,它代表被装载的类 型。如果类型无法被装载,会抛出ClassNotFoundException异常。

class.forName(实例)

Greet.java

package com.xiaoruoen.test;

public class Greet {

public void greet(){

System.out.println("Hello");

}

}

FornameTest.java

package com.xiaoruoen.test;

public class FornameTest {

/**

* @param args

*/

public static void main(String[] args) {

try {

Class c = Class.forName("com.xiaoruoen.test.Greet");

Greet greet = (Greet)c.newInstance();

greet.greet();

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

}

}

动态扩展Java程序的另外一种方式就是使用用户自定义的类装载器的loadClass()方法。如果需要用自定义的类装载器请求类型,只需调用那个类装载器的loadClass()方法。类ClassLoader包含两个名为loadClass()的重载方法,其形式如下:

public Class< > loadClass(String name) throws ClassNotFoundException {

return loadClass(name, false);

}

protected synchronized Class< > loadClass(String name, boolean resolve)

throws ClassNotFoundException

{

// First, check if the class has already been loaded

Class c = findLoadedClass(name);

if (c == null) {

try {

if (parent != null) {

c = parent.loadClass(name, false);

} else {

c = findBootstrapClass0(name