假设我有这样的情况:
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的方法上看到注释吗?
答案 0 :(得分:8)
使用以下课程:
/**
* 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();
}
}
可以致电: 方法me =(new Util.MethodNameHelper(){})。getMethod();
我在该类中广泛使用了getName()调用。在我的机器上,这些匿名类实例化和方法调用往往每个花费大约1500 ns。在我的性能测试中,StackElement行走方法在我的机器上花费了大约30倍(47000 ns)。
答案 1 :(得分:6)
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
Class callerClass = Class.forName(stack[stack.length-2].getClassName());
callerClass.isAnnotationPresent(...)
上面的代码在类上查找注释。您可以组合类名和方法名(也来自堆栈跟踪元素)并查看方法。请注意,这非常慢。
答案 2 :(得分:5)
您需要获取代表调用stringForThisVisibility
的方法的Method
对象。遗憾的是,Java并不提供开箱即用的功能。
但是,我们仍然可以通过Thread.currentThread().getStackTrace()
返回的信息获取Method
。该方法返回StackTraceElement
个对象的数组。每个StackTraceElement
对象告诉我们三件事:
getClassName()
)getMethodName()
)getLineNumber()
)可能需要一些实验,但您应该找到该数组中的哪个索引代表您感兴趣的方法(它可能是数组中的第一个,第二个或第三个StackTraceElement
。)
获得所需的StackTraceElement
后,您可以使用my answer中针对标题为"Get caller's method (java.lang.reflect.Method)"的问题的技术获取其对应的Method
对象。即使该类具有多个具有该方法名称的方法,该技术仍然会说出来。如果您不担心这种情况,可以使用更简单的技术。
获得Method
对象后,只需拨打method.getAnnotation(VisibilityLevel.class)
即可。