当前位置:编程学习 > JAVA >>

谈谈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 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,