Java 反射进行动态方法调用

来源:互联网 发布:李炎恢php第一季素材 编辑:程序博客网 时间:2024/05/22 14:32
Java 反射进行动态方法调用
  设计问题:正在做一个工业系统的仿真软件。仿真的过程在逐步的细化中,因此仿真的核心类处于不断的变化中,有时候会增加新的成员数据(当然,也就增加相应的getter/setter函数)。
仿真的计算只有在外部设置了所有的数据后方可进行。这些数据按照标签名字存在数据库中。
因此,我希望能够根据一个String属性:tag,自动的获得数据库中的数据,并调用仿真类Simu的对应setter函数设定值。同时,不因为后续增加标签而在代码中增加更多的显式调用Simu.setTag(double value)一类的函数。
目前系统中的标签有147个。

用java的反射功能,可以很容易的实现。
首先,在一开始,建立一个保存Simu类所有getter/setter的Hashtable。

import java.lang.Class;
import java.lang.reflect.Method;
import java.util.regex.Pattern;
import java.util.Hashtable;
/** 我希望用反射来调整自动调用的行为*/
public class TagFactory{
    static Class cls;
    /**这里保存标签和方法的映射*/
    static Hashtable<String, Method> getMethods= null;
    static Hashtable<String, Method> setMethods= null;
    private static void initTags(){
        getMethods = new Hashtable<String, Method>();
        setMethods = new Hashtable<String, Method>();
       
        /**从单件中获得仿真类的类型数据*/
        cls = SimucalcSingleton.getSimucalc().getClass();
        /**从仿真类中获取所有的方法*/
        Method methods[] = cls.getMethods();
       
        /**定义正则表达式,从方法中过滤出getter / setter 函数,以及其标签*/
        String gs = "get(//w+)";
        Pattern getM = Pattern.compile(gs);
        String ss ="set(//w+)";
        Pattern setM = Pattern.compile(ss);
        String rapl = "$1";
        String tag;
        for(int i = 0; i < methods.length; ++i) {
            Method m = methods[i];
            String methodName = m.getName();
            if (Pattern.matches(gs, methodName )) {
               tag = getM.matcher(methodName).replaceAll(rapl).toLowerCase();
               getMethods.put(tag, m);
            }
            else if (Pattern.matches(ss, methodName )) {
               tag = setM.matcher(methodName).replaceAll(rapl).toLowerCase();
               setMethods.put(tag, m);
            }
            else System.out.println(methodName + " cannot match");
        }
    }

/**通过这个初始化函数,所有的getter/setter方法就全部保存在hashtable中了。以后可以用标签方便的调用。
* 下面演示如何调用setTagValue 函数向仿真类设定值
*/
    public static boolean setTagValue(String tag, double value) {
/**从hashtable中直接得到对应tag的setter函数对象*/
Method m = setMethods.get(tag.toLowerCase());
            if (m != null){
                try{
                  /**调用仿真类的setter函数*/
                    m.invoke(SimucalcSingleton.getSimucalc(), value);
                    return true;
                }catch (Exception ex){
                    System.out.println("invoke getter on " + tag + " error: " + ex.toString());
                    return false;
                }
            }
        }

通过这种方法,在具体设定值的时候,就可以简单的几句话了。

   public void setVaribles(int seq_id)
    {
        for(Enumeration e = tags.getEnumerator(); e.hasMoreElements();) {
            String tag = (String)e.nextElement();
            /**这个函数会从数据库中取得相应的标签值*/
            setTagValue(tag, getFromDB(tag, seq_id));
           
        }
    }
如果不用反射,需要写147行代码。而且,还缺乏灵活性和扩展性。
 
原创粉丝点击