请参阅java关于调用方法的注释



假设我有这样一个情况:

public String method(String s) {
    return stringForThisVisibility(s, EnumVisibility.PUBLIC);
}

,我想用这样的注释替换它:

@VisibilityLevel(value = EnumVisibility.PUBLIC)
public String method(String s) {
    return stringForThisVisibility(s);
}

这似乎是一个更好和更清晰的解决方案,但我需要stringForThisVisibility方法来知道@VisibilityLevel的值与某种反射。这可能吗?我能看到调用stringForThisVisibility的方法上的注释吗?

使用以下类:

 /**
   * Proper use of this class is
   *     String testName = (new Util.MethodNameHelper(){}).getName();
   *  or
   *     Method me = (new Util.MethodNameHelper(){}).getMethod();
   * the anonymous class allows easy access to the method name of the enclosing scope.
   */
  public static class MethodNameHelper {
    public String getName() {
      final Method myMethod = this.getClass().getEnclosingMethod();
      if (null == myMethod) {
        // This happens when we are non-anonymously instantiated
        return this.getClass().getSimpleName() + ".unknown()"; // return a less useful string
      }
      final String className = myMethod.getDeclaringClass().getSimpleName();
      return className + "." + myMethod.getName() + "()";
    }
    public Method getMethod() {
      return this.getClass().getEnclosingMethod();
    }
  }

可以调用:Method me = (new Util.MethodNameHelper(){}).getMethod();

我在该类中大量使用了getName()调用。在我的机器上,那些匿名的类实例化加上方法调用每次花费大约1500ns。在我的性能测试中,StackElement遍历方法在我的机器上花费了大约30倍的时间(47000 ns)。

需要获取代表调用stringForThisVisibility的方法的Method对象。遗憾的是,Java并没有提供这种开箱即用的功能。

但是,我们仍然可以通过Thread.currentThread().getStackTrace()返回的信息得到Method。该方法返回一个StackTraceElement对象数组。每个StackTraceElement对象告诉我们三件事:

  • 类的名称 (getClassName())
  • 方法的名称 (getMethodName())
  • 行号(getLineNumber())

这可能需要一些实验,但是您应该找到该数组中的哪个索引代表您感兴趣的方法(它可能是数组中的第一个、第二个或第三个StackTraceElement)。

一旦您有了所需的StackTraceElement,您就可以使用我对题为"获取调用者的方法(java.lang.reflect.Method)"的问题的回答中的技术获得其相应的Method对象。即使类有多个具有该方法名的方法,该技术仍将保持不变。如果你不担心这种情况,有一些更简单的技巧。

一旦有了Method对象,就只需要调用method.getAnnotation(VisibilityLevel.class)

可以。

之类的东西
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
Class callerClass = Class.forName(stack[stack.length-2].getClassName());
callerClass.isAnnotationPresent(...)
上面的代码在类上查找注释。您可以组合类名和方法名(同样来自堆栈跟踪元素),然后查看方法。请注意,这是非常慢的

相关内容

  • 没有找到相关文章

最新更新