简体   繁体   English

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

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

I need quite the opposite of what most people want to juggle with: I have a StackTraceElement with className and methodName. 我需要与大多数人想要解决的问题完全相反:我有一个带有className和methodName的StackTraceElement。 As the method belongs to an interface given class implements, I need a way I can ask the method which interface it originates in. 由于该方法属于给定类实现的接口,我需要一种方法可以询问该方法源自哪个接口。

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'. 我可以调用Class.forName(className)并且也可以调用clazz.getMethod(methodName) ,但是method.getDeclaringClass()返回所提到的类'name而不是其原始接口'。 I don't want to iterate through all the class' interfaces to find that particular method, that would practically nullify the performance. 我不想迭代所有类的接口来找到特定的方法,这实际上会使性能无效。

-- -

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: 很抱歉在这里添加它,但是在评论中添加它有点太长了:

My solution was similar to what Andreas is referring to: 我的解决方案类似于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.");
  }
}

Using an invocationContext like structure enables to make an interceptor, so the transmitter can only contain annotated methods with empty implementation bodies. 使用类似结构的invocationContext可以创建一个拦截器,因此发送器只能包含带有空实现主体的带注释的方法。

I have a StackTraceElement with className and methodName. 我有一个带className和methodName的StackTraceElement。
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. 我不想迭代所有类的接口来找到特定的方法,这实际上会使性能无效。

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

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

Result: 结果:

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

I can't imagine why you would need this in a performance sensitive situation but you could cache the results of your search. 我无法想象为什么你会在性能敏感的情况下需要它,但你可以缓存搜索结果。 Note: the same method might implement a method from many interfaces. 注意:相同的方法可能会从许多接口实现一个方法。

I don't want to iterate through all the class' interfaces to find that particular method, that would practically nullify the performance. 我不想迭代所有类的接口来找到特定的方法,这实际上会使性能无效。

I don't think there are any alternatives. 我认为没有其他选择。

(But to echo what Peter Lawrey says, caching would help ... and reflection in general should be avoided if performance matters.) (但是为了回应Peter Lawrey所说的,缓存会有所帮助......如果性能很重要,应该避免反思。)

Also note: 另请注意:

  • A given method might not be declared in any interface. 可能未在任何接口中声明给定方法。
  • A given method night be declared in more than one interface, or in an interface that is inherited via multiple paths. 给定方法之夜可以在多个接口中声明,也可以在通过多个路径继承的接口中声明。

Your scheme has to take account of these things if it is to be truly general. 你的计划必须考虑到这些事情,如果它是真正的一般。


It is guaranteed that one method belongs only to one interface. 保证一种方法只属于一个接口。

Even so ... 即使是这样 ...

暂无
暂无

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

相关问题 如何将实现的接口对象传递给其实现的类中的方法? - How do I pass an implemented Interface object to a method in the class its implemented in? 如何找到继承给定接口的类实例? - How do I find class instances that inherit a given interface? Java 谓词接口 - 该方法如何工作 - 虽然它没有在我的 class 中实现 - Java Predicate Interface - How the method is working - Though it is not implemented in my class 如何找到我的类用作某个实现接口的用法? - How do I find usages of my class where it is used as a certain implemented interface? 如何在参数为Java基类的方法中构造派生类的对象? - How do I construct an object of a derived class in a method whose argument is a base class in Java? 如何在接口中参数化然后在实现的类中指定泛型 - How do I parameterise in an interface and then specify generic type in implemented class 如何更改从实现到我正在使用的具体类的接口覆盖的方法的签名? - How do I change the signature of a method I have overriden from my interface that I implemented onto the concrete class I'm using? JAVA:access方法在类中定义,但未通过其接口实现 - JAVA :access method defined in class , but not implemented by its interface 我如何实现一个泛型类,该类在java中调用指定接口的静态方法 - How do i implement a generic class that calls a static method of specified interface in java 如何在java中找到已实现接口的所有子类? - How to find all sub classes of implemented interface in java?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM