通过存储在哈希表中的字符串访问函数

时间:2009-09-06 15:12:45

标签: java java-me methods hashtable hecl

如果我将函数名称存储为Hashtable中的字符串 有没有办法通过存储的字符串访问函数?

EDIT 我担心我在CLDC1.1 / MIDP2.0上工作的平台不支持Reflection 有可能解决方法吗?

5 个答案:

答案 0 :(得分:4)

只需使用一长串else-ifs:

[...]
} else if ("foo".equals(function)) {
    target. foo();
} else if ("bar".equals(function)) {
    target. bar();
[...]

(虽然我一般不喜欢在源代码中尝试垂直对齐,但我认为在这种情况下这是值得的。)

在地图中存储仿函数是另一种选择,对于许多MIDP应用程序来说,bu可能会增加对象的大小。

答案 1 :(得分:4)

Class.forName()和newInstance()应该在MIDP 1.1上,可能会有用。由于您没有完全反射,因此可以创建一个包装所有函数调用并调用它们的类。这假设您事先知道所有函数调用。

除非您正在进行静态调用,否则您需要引用所有对象。有点凌乱,但会完成工作。

public Object invoke(String name, Object[] args) {
   Object f = functionMap.get(name);
   if("f1".equals(name)) {
       return ((SomeInterface1)f).someFunction1((SomeArg0) args[0]), ...);
   } else if ("f2".equals(name)) {
       return ((SomeInterface2)f).someFunction2((SomeArg0) args[0]), ...);
   }...{
   } else if ("fN".equals(name)) {
       return ((SomeInterfaceN)f).someFunctionN((SomeArg0) args[0]), ...);
   }
}

答案 2 :(得分:2)

给定函数名称,您可以使用反射来访问该方法。除了函数的名称,你需要知道它的类,并且(或者通过反射创建,如果它有一个noarg构造函数,或者你知道传递给构造函数的参数)一个实例(如果方法不是静态的)和你必须知道传递给它的参数。

另一种选择是使用Method类作为指向函数的指针。它具有了解其类并了解其参数要求的优点。它的缺点是不能序列化。

编辑:只有将其名称作为字符串,才能在没有反射的情况下访问Java中的方法。如果你想要一个指向方法的替代指针,你可以使用一个匿名内部类来调用你想要实现已知接口的方法并将其传递给你的地图。这不适合作为地图的关键,但它可以作为地图中的值。

答案 3 :(得分:2)

我没有尝试过对javame的反思,但是在javase上你可以使用反射来动态调用方法。

以下摘录摘自: http://java.sun.com/developer/technicalArticles/ALT/Reflection/

import java.lang.reflect.*;

public class method2 {       public int add(int a,int b)       {          返回a + b;       }

  public static void main(String args[])
  {
     try {
       Class cls = Class.forName("method2");
       Class partypes[] = new Class[2];
        partypes[0] = Integer.TYPE;
        partypes[1] = Integer.TYPE;
        Method meth = cls.getMethod(
          "add", partypes);
        method2 methobj = new method2();
        Object arglist[] = new Object[2];
        arglist[0] = new Integer(37);
        arglist[1] = new Integer(47);
        Object retobj 
          = meth.invoke(methobj, arglist);
        Integer retval = (Integer)retobj;
        System.out.println(retval.intValue());
     }
     catch (Throwable e) {
        System.err.println(e);
     }
  }

}

编辑: 您可能希望实际传回一个数字,并使用开关,而不是使用if..then..else,因为它更容易阅读,IMO。

但是,无论如何,考虑到JavaME的限制,这可能是您唯一的选择。

答案 4 :(得分:1)

我处理Hecl中的类似问题,这是一个在J2ME上运行的解释器。它取决于你想要处理多少个字符串,但一个有效的方法是使用散列来查找一个整数,然后在switch语句中使用它,而不是if / then语句的大列表。顺便说一句,欢迎您使用Hecl源代码;它可以在自由派Apache许可下使用。