如何找到在给定类中实现其方法的Java接口?

如何找到在给定类中实现其方法的Java接口?,java,reflection,methods,interface,Java,Reflection,Methods,Interface,我需要的与大多数人想要处理的恰恰相反:我有一个带有className和methodName的StackTraceElement。由于该方法属于给定类实现的接口,因此我需要一种方法来询问该方法它来自哪个接口 我可以调用Class.forName(className),也可以调用clazz.getMethod(methodName),但是method.getDeclaringClass()返回所提到的类“名称,而不是其原始接口”。我不想遍历所有类的接口来找到特定的方法,这实际上会使性能失效 -- 基

我需要的与大多数人想要处理的恰恰相反:我有一个带有className和methodName的StackTraceElement。由于该方法属于给定类实现的接口,因此我需要一种方法来询问该方法它来自哪个接口

我可以调用
Class.forName(className)
,也可以调用
clazz.getMethod(methodName)
,但是
method.getDeclaringClass()
返回所提到的类“名称,而不是其原始接口”。我不想遍历所有类的接口来找到特定的方法,这实际上会使性能失效

--

基本上,它是一种传统的广播机制。广播器类包含一个hashmap,其中键是接口,值是带有实现类的列表。广播器实现相同的接口,以便每个方法从hashmap检索实现类,对它们进行迭代,并在每个实现类上调用相同的方法

--

很抱歉将其添加到此处,但添加到评论中有点太长:

我的解决方案与Andreas所指的类似:

StackTraceElement invocationContext = Thread.currentThread().getStackTrace()[2];
Class<T> ifaceClass = null;
Method methodToInvoke = null;
for (Class iface : Class.forName(invocationContext.getClassName()).getInterfaces()) {
  try {
    methodToInvoke = iface.getMethod(invocationContext.getMethodName(), paramTypes);
    ifaceClass = iface;
    continue;
  } catch (NoSuchMethodException e) {
    System.err.println("Something got messed up.");
  }
}
StackTraceeElement invocationContext=Thread.currentThread().getStackTrace()[2];
类ifaceClass=null;
方法methodToInvoke=null;
for(Class-iface:Class.forName(invocationContext.getClassName()).getInterfaces()){
试一试{
methodToInvoke=iface.getMethod(invocationContext.getMethodName(),paramTypes);
ifaceClass=iface;
继续;
}捕获(无此方法例外){
System.err.println(“有些东西搞砸了。”);
}
}

使用类似于
invocationContext
的结构可以生成拦截器,因此发送器只能包含带有空实现体的带注释的方法。

我无法想象在性能敏感的情况下为什么需要它,但可以缓存搜索结果。注意:同一个方法可能从许多接口实现一个方法

我不想遍历所有类的接口来找到特定的方法,这实际上会使性能失效

我认为没有其他选择

(但与Peter Lawrey的说法相呼应的是,缓存会有所帮助……如果性能很重要,一般来说应该避免反射。)

另请注意:

  • 给定的方法可能不会在任何接口中声明
  • 给定的方法可以在多个接口中声明,也可以在通过多个路径继承的接口中声明
如果你的计划要真正具有普遍性,就必须考虑到这些因素



保证一个方法只属于一个接口

即便如此

我有一个带有className和methodName的StackTraceElement。
我需要一种方法,我可以询问它来自哪个接口的方法
我不想遍历所有类的接口来找到特定的方法,这实际上会使性能失效

我首先要检查在您的用例中迭代所有类接口是否真的对性能至关重要。通常,当您有一个堆栈跟踪元素时,您已经处于一种异常状态,在这种状态下,性能可能没有那么关键。然后可以使用
Class.getInterfaces()
遍历接口并查询每个接口的声明方法,例如:

class MethodQuery {
   private Set<Class<?>> result = new HashSet<>();
   private String theMethodName;

   private void traverse(Class<?> cls) {
      for (Class<?> c : cls.getInterfaces()) {
         for (Method m : c.getDeclaredMethods()) {
            if (theMethodName.equals(m.getName())) {
               result.add(c);
            }
         }

         traverse(c);
      }
   }

   public Set<Class<?>> getInterfacesForMethod(Class<?> cls, String methodName) {
      result.clear();
      theMethodName = methodName;
      traverse(cls);
      return result;
   }
}
MethodQuery methodQuery = new MethodQuery();
Set<Class<?>> result = 
    methodQuery.getInterfacesForMethod(java.util.Vector.class, "addAll");
System.out.println(result);

您是否尝试过
Class.getInterfaces()
在您的用例中是否真的对性能至关重要?可以保证一个方法只属于一个接口。Andreas,请添加您的注释作为答案?我最后选择了Class.getInterfaces(),似乎可以做到这一点。给定的方法在一个且只有一个接口中声明,但是该接口由多个类实现。一个类已经包含了一个HashMap和其他实现类,其中接口是键。这就是为什么我需要接口,这样我就可以将每个方法调用广播给所有其他实现类。
[interface java.util.Collection, interface java.util.List]