java动态加载类

 

/*

JAVA中,通过Class.forName()方法可以动态决定加载哪一个类,这个功能对于相同接口的不同实现来讲非常有用。比如对于设计好的数据库连接池接口,我们可以有多种的接口实现类来完成相同的功能,同时用户可以简单的通过修改配置文件来指定实际使用哪一个实现类,在源代码里面通过读取配置文件信息,并用Class.forName(configClassName).getInstance()就可以构造一个特定的实现类实例,而不用每次修改源代码。这样对于程序来讲只用关心接口的定义,用户只用进行配置文件的设置就完成了同一功能的不同实现的切换。

但是如果实现类需要通过静态方法来进行初始化的时候,动态加载的过程就会复杂一些。同样的以数据库连接池为例,通常连接池的构造函数都会被定义为私有的,而通过自定义的getInstance()静态方法来得到唯一实例。这种情况下简单的通过Class.forName().getInstance()就无法正确构造实例。

幸好JAVA所提供的反射机制(Reflection)为我们提供了完整了探悉类内部结构的方法。通过反射机制,我们能够完成基本上所有的运行时决定的动作(虽然这一实现要比其他动态语言,比如PHP,的eval()的使用要复杂的多)

下面通过实际的例子说明如何在运行时动态访问类的静态方法。

-------------------------------------------------------

*/

import java.lang.reflect.*;

public class myTestClass{

    private static Object pLock = new Object();

    private static myTestClass p_instance = null;

    private String s_configName = "";

    private boolean b_isFromResource = true;

    public static Object getInstance(String sConfigName,

                                         Boolean bIsFromResource){

        synchronized(pLock){

            if(null == p_instance){

                 p_instance =

                    new myTestClass(sConfigName,bIsFromResource);

             }

         }

        return p_instance;

     }

    private myTestClass(String sConfigName,Boolean bIsFromResource){

         s_configName = sConfigName;

         b_isFromResource = bIsFromResource.booleanValue();

     }

    public void echoInfo(){

         System.out.println("current arguments : configName=["+

                             s_configName+"],isFromResource=["+

                             b_isFromResource+"]");

     }

    public static void main(String[] args) throws Exception{

        // 设置方法的传入参数的类型.

         Class[] parameterTypes = new Class[]{

                                     java.lang.String.class,

                                     java.lang.Boolean.class

                                     };

         Method mGetInstance = null;

         String className = "myTestClass";

         Class curTestClass = Class.forName(className);

        try{

             mGetInstance = curTestClass.

                             getMethod("getInstance",parameterTypes);

         }

        catch(NoSuchMethodException e){

             e.printStackTrace();

             mGetInstance = null;

         }

        if(mGetInstance != null){

             myTestClass pObj = (myTestClass)

                                 mGetInstance.invoke(

                                    null,

                                    new Object[]{

                                        "src/myconfig.properties",

                                         Boolean.FALSE

                                     }

                                 );

             pObj.echoInfo();

         }

        else{

            throw

            new Exception("myTest Init Failed from class" +

                                 className +

                                 System.getProperty("line.seperator","/n") +

                                "method getInstance(String, Boolean) exists.");

         }

     }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值