谈谈Java虚拟机3——动态扩展
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);
}
} catch (ClassNotFoundException e) {
// If still not found, then invoke findClass in order
 
补充:软件开发 , Java ,