2010-08-24 117 views
3

首先让我说我正在维护别人设计不好的代码,所以我限制了我可以改变它的程度。Java反射,其中一个方法参数是一个接口

现在发生的是他们创建了一系列反射调用的方法。其中一种方法将Map作为其参数之一。在运行时,这个Map是用一个Hashtable实现的。

下面是问题 - 我得到一个NoSuchMethodException,因为它正在寻找一个Hashtable作为参数的方法,即使Hashtable实现了Map接口。令我困惑的是,如果我不使用反射(这种情况下的主要设计更改)并传递了一个Hashtable,它将使用Map参数调用该方法 - 那么,为什么当我使用反射时它的工作方式不同?

鉴于我几乎必须坚持反思有没有什么办法让我的方法与Map参数调用,当我通过它实现该接口的类?

如果你想我可以嘲笑一些代码最多演示...

回答

4

如果从java.lang.Class使用getMethod(String name, Class[] parameterTypes),则需要指定接口的方法签名(静态类型)中所表示的参数类型,而不是运行时(动态类型)的对象类型。

因此,对于methodXyz(Map map),而不是:

Method m = cl.getMethod("methodXyz", new Class[]{argument.getClass()}); 

做到这一点:

Method m = cl.getMethod("methodXyz", new Class[]{Map.class}); 
+0

问题是大概有20种方法被称为methodXyz与工作就好了各种争论。只有这个新的地图将Map作为导致问题的论据。 我可以做你所说的,但是这需要我确定是否有问题的参数是一个地图首先使用instanceof例如:) 我不明白为什么反射的操作方式与非反射代码的操作方式不同查找方法?!?!它必须使用完全不同的机制,我猜... – BigMac66 2010-08-24 17:19:29

+0

getMethod()需要定义的确切类型。这就是为什么它被命名为getMethod()而不是findMethod()。如果你经常在做动态方法调度,你可以编写你自己的findMethod()。这将涉及查找具有proprer名称的方法,过滤参数与给定参数不相容的方法并处理多于一种方法仍然是候选者的情况,例如,下面的情况是不明确的,并且是编译错误:new StringBuffer()。append(null)。 – gawi 2010-08-24 17:42:24

1

我也有类似的问题。我看到2个解决方案:

解决方案1:您可以开发更复杂的搜索方法。算法的

例如,你可以使用:

You search with the parameter type. If the search fails (Exception), but one of the parameters has a super type (or implements an interface), you search the same method name, but with this superclass (or interface). You throw the exception only if no method is found after this search algorithm.

注意:如果你的方法有几个参数时,一定要确认与超类型/接口的每个可能的组合。它可能会导致一个相当复杂的搜索算法...

解决方案2:另一种方法,更容易,是与参数分开精确的类型。如果您想使用空参数,则可能需要更详细的此方法。

所以, “的InvokeMethod(字符串方法名,对象[] paramters)” 变成 “的InvokeMethod(字符串方法名,类[] methodParamTypes,对象[]参数)”。

相关问题