以超类为参数的类反射查找方法

时间:2013-09-11 09:41:10

标签: java generics reflection

关于我无法理解的事情的小问题。我有以下内容:

public abstract class A 
{
  ...
}

以及此课程的扩展

public class B extends A
{
 ...
}

现在我有一个类如下的

public class DoStuff extends AbstractDoStuff
{
  public void doNiceStuff(B b)
  {
    ...
  }
}

这是我试图通过反射调用的这个类'方法。但是我试图从一个不知道B的包中调用这个方法,只知道A。这是由于项目的依赖性

所以我有以下代码需要找到方法doNiceStuff(B):

public abstract class AbstractDoStuff
{
  public static Method getGetterMethod(Class<? extends AbstractDoStuff> stuffClass) throws NoSuchMethodException
  {
    Method method = stuffClass.getDeclaredMethod("doNiceStuff", A.class)
    ...
  }
}

所以getDeclaredMethod应该在类DoStuff上找到doNiceStuff,但似乎反射无法使用超类A.class找到该方法。但是我不能提供B.class,因为包不知道B的存在。

是否有办法解决这个问题?

问候

迈克尔

1 个答案:

答案 0 :(得分:2)

您可以使用更多反射来获取它:

Method[] methods = stuffClass.getMethods(); 
for(Method m: methods) {
   if(m.getName().equals("doNiceStuff")) {
      Class<?> paramTypes = m.getParameterTypes();

      //condition on the desired parameter types comes here
      if(paramTypes.length==1 && A.class.isAssignableFrom(paramTypes[0]) {
        //we found it!
      }

   }
}

为什么isSuperClass()在这种情况下不好?

假设我们这样做:

if (paramTypes.length == 1 && paramTypes[0].getSuperclass().equals(A.class)) {
...

此解决方案适用于课程B,但如果我们有课程C怎么办?

public class C extends B {


    public void doNiceStuff(C arg0) {
        //do nice stuff here
    }

}

这个条件

paramTypes[0].getSuperclass().equals(A.class)

会是假的! paramTypes [0] .getSuperClass()为B.class,不等于A.class ......

<强> Class.getMethods()

  

返回一个包含Method对象的数组,该对象反映此Class对象所表示的类或接口的所有公共成员方法,包括由类或接口声明的那些以及从超类和超接口继承的那些。

<强> Class.isAssignableFrom()

  

确定此Class对象表示的类或接口是否与指定的Class参数表示的类或接口相同,或者是它们的超类或超接口。如果是这样,它返回true;否则返回false。如果此Class对象表示基本类型,则如果指定的Class参数恰好是此Class对象,则此方法返回true;否则返回true。否则返回false。   具体来说,此方法测试是否可以通过标识转换或扩展引用转换将指定的Class参数表示的类型转换为此Class对象表示的类型。有关详细信息,请参阅Java语言规范,第5.1.1和5.1.4节。

推荐阅读: