方法参数是接口的Java反射

时间:2010-08-24 16:22:50

标签: java reflection interface

首先请允许我说我维护其他设计不佳的代码,因此我可以更改它的数量有限。

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

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

鉴于我几乎不得不坚持使用反射,当我向其传递一个实现该接口的类时,是否有任何方法可以获取调用Map参数的方法?

如果你想我可以模拟一些代码来演示...

2 个答案:

答案 0 :(得分:4)

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

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

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

这样做:

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

答案 1 :(得分:1)

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

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

您可以使用的算法示例:

  

您使用参数类型进行搜索。如果搜索失败(Exception),但其中一个参数具有超类型(或实现接口),则搜索相同的方法名称,但使用此超类(或接口)。   只有在此搜索算法之后找不到任何方法时才抛出异常。

注意:如果您的方法有多个参数,请务必使用每种可能的超类型/接口组合进行验证。它可能导致一个非常复杂的搜索算法...

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

所以,“ invokeMethod(String methodName,Object [] paramters)”变成“ invokeMethod(String methodName, Class [] methodParamTypes ,Object []参数)”。