[英]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: 另请注意:
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.