我正在编写消息传递组件,出于某些原因,我需要找出哪些类的方法可以被消息传递组件调用。在其他标准中,这些方法需要实现特定的接口。如何通过反射找出这些方法?我有权访问该类,但我不能依赖于方法名称。类中可能有类似的方法具有相同的名称但不实现所需的(或任何)接口。例如:
interface A
{
long set(Object object)
}
class B implements A
{
public long set(Object object)
{
System.out.println("I am the method they are looking for!");
}
public void set(int i, int j)
{
System.out.println("I am not the qualifying method!");
}
}
所以,简而言之,我想通过反射而不是第二种方法找到第一种方法。这在Java中是否可行?
答案 0 :(得分:-1)
您可以使用以下命令建立声明方法的接口列表:
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class B extends D implements A {
public Long set(Object object) {
System.out.println("I am the method they are looking for!");
return (long) 0;
}
public void set(int i, int j) {
System.out.println("I am not the qualifying method!");
}
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
Method methodToCheck = B.class.getDeclaredMethod("set", Object.class);
List<Class<?>> declaringInterfaces = searchForDeclaringInterfaces(methodToCheck, B.class);
System.out.println("The method " + methodToCheck + " is declared in these interfaces:");
for (Class<?> c : declaringInterfaces) {
System.out.println(c.getCanonicalName());
}
}
public static List<Class<?>> searchForDeclaringInterfaces(Method methodToCheck, Class<?> clazz)
throws NoSuchMethodException {
if (clazz == null) {
return Collections.EMPTY_LIST;
}
LinkedList<Class<?>> declaringInterfaces = new LinkedList<>();
for (Class<?> c : clazz.getInterfaces()) {
Method methodFromInterface = searchMethods(c.getDeclaredMethods(), methodToCheck.getName(),
methodToCheck.getParameterTypes());
if (methodFromInterface != null) {
declaringInterfaces.add(c);
}
}
declaringInterfaces.addAll(searchForDeclaringInterfaces(methodToCheck, clazz.getSuperclass()));
return declaringInterfaces;
}
private static Method searchMethods(Method[] methods, String name, Class<?>[] parameterTypes) {
Method res = null;
String internedName = name.intern();
for (int i = 0; i < methods.length; i++) {
Method m = methods[i];
if (m.getName() == internedName && arrayContentsEq(parameterTypes, m.getParameterTypes())
&& (res == null || res.getReturnType().isAssignableFrom(m.getReturnType())))
res = m;
}
return res;
}
private static boolean arrayContentsEq(Object[] a1, Object[] a2) {
if (a1 == null) {
return a2 == null || a2.length == 0;
}
if (a2 == null) {
return a1.length == 0;
}
if (a1.length != a2.length) {
return false;
}
for (int i = 0; i < a1.length; i++) {
if (a1[i] != a2[i]) {
return false;
}
}
return true;
}
}
interface A extends C {
public Number set(Object object);
}
interface C {
Number set(Object object);
}
class D implements C {
@Override
public Number set(Object object) {
return null;
}
}
这将打印:
The method public java.lang.Long B.set(java.lang.Object) is declared in these interfaces:
A
C
它打印B类树中所有接口并声明此方法。
答案 1 :(得分:-1)
是......而且没有。
遍历类的超类和接口的DAG,为每个类调用getDeclaredMethods()
以获取在接口中声明的一组Method
个对象。然后查找该集与该类本身的声明方法集之间的匹配。
一个问题是类中的给定方法可以实现多个接口声明的抽象方法。
第二个问题是决定匹配语义的正确(对于你的应用程序!)方法并实现它。 (请注意,您的示例只是一个示例。它没有指定任何语义。)