How to find the Java interface whose method is implemented in this class?

I need the exact opposite of what most people want to manipulate: I have a StackTraceElement with className and methodName. Since the method refers to the interface defined by the class, I need a way by which I can set the method with which it interacts.

I can call Class.forName(className)and also call clazz.getMethod(methodName), however it method.getDeclaringClass()returns with the specified class name instead of its original interface. I do not want to iterate over all the interfaces of the class to find this specific method, which practically negates performance.

-

This is basically an old broadcast mechanism. The broadcaster class contains a hash map where the keys are interfaces and the values ​​are lists with implementation classes. The transmitter implements the same interface so that each method retrieves the implementation classes from the hash map, iterates through them and calls the same method for each implementing class.

-

Sorry to add it here, but it is too long to add it to the comment:

My decision was similar to what Andreas was talking about:

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 invocationContextthis structure allows you to make an interceptor, so the transmitter can only contain annotated methods with empty areas of implementation.

+2
source share
3 answers

StackTraceElement className methodName.
, , ,
  , , .

, . , , , . 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]
+2

, , , . : .

+2

, , .

, .

( , , ... , .)

:

  • .
  • , .

, .


It is guaranteed that one method belongs to only one interface.

Even so...

+1
source

Source: https://habr.com/ru/post/1651929/


All Articles