如何找到在给定类中实现其方法的Java接口? [英] How do I find the Java interface whose method is implemented in a given class?

查看:195
本文介绍了如何找到在给定类中实现其方法的Java接口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need quite the opposite of what most people want to juggle with: I have a StackTraceElement with className and methodName. As the method belongs to an interface given class implements, I need a way I can ask the method which interface it originates in.

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

I can invoke Class.forName(className) and can also invoke clazz.getMethod(methodName), however method.getDeclaringClass() returns with the mentioned class' name instead of its original interface'. I don't want to iterate through all the class' interfaces to find that particular method, that would practically nullify the performance.

-

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

Basically it is a legacy broadcast mechanism. A broadcaster class contains a hashmap, where the keys are interfaces, and the values are lists with the implementing classes. The broadcaster implements the same interface so that each method retrieves the implementing classes from the hashmap, iterates through them and invokes the same method on each implementing class.

-

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

Sorry for adding it here, but it's a bit too long to add it inside a comment:

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

My solution was similar to what Andreas is referring to:

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 like结构可以创建拦截器,因此发送器只能包含带有空实现主体的带注释方法。

Using an invocationContext like structure enables to make an interceptor, so the transmitter can only contain annotated methods with empty implementation bodies.

推荐答案


我有一个带有className和methodName的StackTraceElement。

我需要一种方法我可以问一下它起源于哪个接口的方法

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

I have a StackTraceElement with className and methodName.
I need a way I can ask the method which interface it originates in
I don't want to iterate through all the class' interfaces to find that particular method, that would practically nullify the performance.

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

I would first check whether iterating through all the class interfaces is really performance critical in your usecase. Usually, when you have a stack trace element, you are already in an exceptional state where performance might not be that critical. You could then use Class.getInterfaces() to traverse the interfaces and query the declared methods for each interface, for example like this:

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;
   }
}

然后,您可以查询方法声明的接口:

You can then query which interface a method declares like this:

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]

这篇关于如何找到在给定类中实现其方法的Java接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆