请参阅调用方法的java注释
假设我有这样的情况:
public String method(String s) { return stringForThisVisibility(s, EnumVisibility.PUBLIC); }
我想用这样的注释替换它:
@VisibilityLevel(value = EnumVisibility.PUBLIC) public String method(String s) { return stringForThisVisibility(s); }
这似乎是一个更好,更清晰的解决方案,但我需要stringForThisVisibility方法来通过某种reflection来了解@VisibilityLevel的值。 那可能吗? 我可以在调用stringForThisVisibility的方法上看到注释吗?
您需要获取表示调用stringForThisVisibility
的方法的Method
对象。 遗憾的是,Java并不提供开箱即用的function。
但是,我们仍然可以通过Thread.currentThread().getStackTrace()
返回的信息获取Method
。 该方法返回一个StackTraceElement
对象数组。 每个StackTraceElement
对象告诉我们三件事:
- 类的名称 (
getClassName()
) - 方法的名称 (
getMethodName()
) - 行号(
getLineNumber()
)
可能需要一些实验,但你应该找到该数组中的哪个索引代表你感兴趣的方法(它可能是数组中的第一个,第二个或第三个StackTraceElement
)。
获得所需的StackTraceElement
,可以使用我对题为“获取调用者的方法(java.lang.reflect.Method)”的问题的答案中的技术获取其对应的Method
对象。 即使该类具有多个具有该方法名称的方法,该技术仍然会说出来。 如果您不担心这种情况,可以使用更简单的技术。
获得Method
对象后,只需调用method.getAnnotation(VisibilityLevel.class)
。
使用以下课程:
/** * 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()调用。 在我的机器上,这些匿名类实例化和方法调用往往每个花费大约1500 ns。 在我的性能测试中,StackElement行走方法在我的机器上花费了大约30倍(47000 ns)。
是的,你可以。 一些东西
StackTraceElement[] stack = Thread.currentThread().getStackTrace(); Class callerClass = Class.forName(stack[stack.length-2].getClassName()); callerClass.isAnnotationPresent(...)
上面的代码在类上查找注释。 你可以组合类名和方法名(也来自堆栈跟踪元素)并查看方法。 请注意,这非常慢。