Let's say I have a situation like this:
public String method(String s) {
return stringForThisVisibility(s, EnumVisibility.PUBLIC);
}
and I want to replace it with an annotation like this:
@VisibilityLevel(value = EnumVisibility.PUBLIC)
public String method(String s) {
return stringForThisVisibility(s);
}
This seems to be a better and more clear solution, but i need for stringForThisVisibility method to know value of @VisibilityLevel with some kind of reflection. Is that possible? Can I see the annotations on the method calling stringForThisVisibility?
The isAnnotation() method is used to check whether a class object is an annotation. The isAnnotation() method has no parameters and returns a boolean value. If the return value is true , then the class object is an annotation. If the return value is false , then the class object is not an annotation.
Annotations can be applied to declarations: declarations of classes, fields, methods, and other program elements. When used on a declaration, each annotation often appears, by convention, on its own line. As of the Java SE 8 release, annotations can also be applied to the use of types.
With the following 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();
}
}
One can call: Method me = (new Util.MethodNameHelper(){}).getMethod();
I make extensive use of the getName() call in that class. On my machine those anonymous class instantiations plus method invocations tend to cost about 1500 ns each. The StackElement walking approach costs about 30 times as much (47000 ns) on my machine in my performance test.
You need to obtain the Method
object that represents the method that called stringForThisVisibility
. Unfortunately, Java doesn't offer this functionality out of the box.
However, we can still obtain the Method
via the information returned by Thread.currentThread().getStackTrace()
. That method returns an array of StackTraceElement
objects. Each StackTraceElement
object tells us three things:
getClassName()
)getMethodName()
)getLineNumber()
)It may take some experimentation, but you should find which index in that array represents the method you're interested in (it will probably be the first, second or third StackTraceElement
in the array).
Once you have the desired StackTraceElement
, you can obtain its corresponding Method
object using the technique in my answer to the question entitled "Get caller's method (java.lang.reflect.Method)". That technique will still word, even if the class has more than one method with that method name. There are simpler techniques if you're not worried about that scenario.
Once you have the Method
object, it's just a matter of calling method.getAnnotation(VisibilityLevel.class)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With