目前,我有一堆实现
Processor
接口的 Java 类,这意味着它们都有一个 processRequest(String key)
方法。这个想法是每个类都有一些(例如,<10) member Strings
,并且每个类都通过 processRequest
方法映射到该类中的一个方法,如下所示:
class FooProcessor implements Processor
{
String key1 = "abc";
String key2 = "def";
String key3 = "ghi";
// and so on...
String processRequest(String key)
{
String toReturn = null;
if (key1.equals(key)) toReturn = method1();
else if (key2.equals(key)) toReturn = method2();
else if (key3.equals(key)) toReturn = method3();
// and so on...
return toReturn;
}
String method1() { // do stuff }
String method2() { // do other stuff }
String method3() { // do other other stuff }
// and so on...
}
你明白了。
这对我来说工作得很好,但现在我需要一个运行时可访问的从键到函数的映射;并不是每个函数实际上都返回一个字符串(有些返回void),我需要动态访问每个类中每个函数的返回类型(使用反射),每个类都有一个键。我已经有一个了解所有按键的经理,但不知道从按键到功能的映射。 我的第一反应是用
if-else
语句替换此映射,就像我在 Javascript 中所做的那样。但是,Java 不支持一等函数,所以我运气不好。我可能可以找到一个第三方库,让我可以使用一流的函数,但我还没有看到任何库,而且我怀疑我是否需要一个全新的库。
我还考虑过将这些
Map<String, Function>
键放入数组中,并使用反射按名称调用方法,但我发现此方法有两个缺点:
我的键必须以与方法相同的名称命名 - 或者以特定的、一致的方式命名,以便可以轻松地将它们映射到方法名称。这似乎比我现在的
String
if-else
映射到某种 String
对象,我可以在该对象上调用和调用(类似)
Function
。如果第三方库“真的”符合我的需求,我并不特别介意使用它。我也不介意使用反射,尽管我强烈希望避免每次进行方法查找时都使用反射 - 也许使用一些将 getReturnType()
与反射相结合的缓存策略。有什么好方法可以得到我想要的东西吗?干杯! 没有任何一流的独立功能,但您可以通过界面做您想做的事情。创建一个代表您的功能的界面。例如,您可能有以下内容:
Map
public interface ComputeString
{
public String invoke();
}
对象。使用贴图会比反射快得多,并且还会提供更多的类型安全性,所以我建议采用上述方法。
虽然你不能拥有第一类函数,但有可以基于接口的匿名类:
Map<String,ComputeString>
你不能对
interface ProcessingMethod {
String method();
}
Map<String, ProcessingMethod> methodMap = new HashMap<String, ProcessingMethod>();
methodMap.put("abc", new ProcessingMethod() {
String method() { return "xyz" }
});
methodMap.put("def", new ProcessingMethod() {
String method() { return "uvw" }
});
methodMap.get("abc").method();
enum
来调用具有可变数量同质参数的函数,而无需反射。 FunctionAdapter
函数仅使用
lookup()
,但对于大量函数来说,Enum.valueOf
可能是值得的。正如您所注意到的,您可以使用
Reflection API做您想做的事情,但是除了您已经遇到的问题之外,您还失去了 Java 编译器的一些好处。 将您的字符串包装在一个对象中并使用Visitor模式
Map
只会接受具有正确方法或类似方法的 StringWrapper
。
Visitor
反射 API 中的
Method类怎么样?您可以根据名称、参数或返回类型查找类的方法。然后你只需调用 Method.invoke(this,parameters) 即可。