繁体   English   中英

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

[英]How do I find the Java interface whose method is implemented in a given class?

我需要与大多数人想要解决的问题完全相反:我有一个带有className和methodName的StackTraceElement。 由于该方法属于给定类实现的接口,我需要一种方法可以询问该方法源自哪个接口。

我可以调用Class.forName(className)并且也可以调用clazz.getMethod(methodName) ,但是method.getDeclaringClass()返回所提到的类'name而不是其原始接口'。 我不想迭代所有类的接口来找到特定的方法,这实际上会使性能无效。

-

基本上它是传统的广播机制。 广播器类包含散列映射,其中键是接口,值是具有实现类的列表。 广播器实现相同的接口,以便每个方法从散列映射中检索实现类,遍历它们并在每个实现类上调用相同的方法。

-

很抱歉在这里添加它,但是在评论中添加它有点太长了:

我的解决方案类似于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.");
  }
}

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

我有一个带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);

结果:

[interface java.util.Collection, interface java.util.List]

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

我不想迭代所有类的接口来找到特定的方法,这实际上会使性能无效。

我认为没有其他选择。

(但是为了回应Peter Lawrey所说的,缓存会有所帮助......如果性能很重要,应该避免反思。)

另请注意:

  • 可能未在任何接口中声明给定方法。
  • 给定方法之夜可以在多个接口中声明,也可以在通过多个路径继承的接口中声明。

你的计划必须考虑到这些事情,如果它是真正的一般。


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

即使是这样 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM