Disclaimer: I have 10 years’ experience programming, but 8 of which is in PHP (loosely typed) — I have been using Java now for 4 days 🙂
In java, I need to get the value of an annotation for a method in the call stack. As far as I can tell, I do this with the Method object. From the call stack, I have retrieved the names of the class and method (strings). This is the (abbreviated) code that I am using…
Calling Method:
public class myClass
{
@Path( "some/path/value" )
public void myMethod( String someArg ) { ... }
}
Retrieval Code:
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
String callingMethodName = trace[depth].getMethodName();
String callingClassName = trace[depth].getClassName();
Class[] signature = new Class[1];
signature[0] = String.class;
Class callingClass = Class.forName( callingClassName );
Method callingMethod = callingClass.getMethod( callingMethodName, signature );
Path annotation = callingMethod.getAnnotation( Path.class );
This works like a charm, successfully returning the value of the @Path annotation ("some/path/value")
However, if you notice, I had to supply a signature of the method I was looking for. As you can see in the class code, there is only 1 method with that name, so, theoretically, the signature of the method should be irrelevant, right? As far as I can tell from various docs/blogs/examples, I should be able to call getMethod( ) with either no 2nd argument, or with null for the 2nd argument, but if I use the following:
Class callingClass = Class.forName( callingClassName );
Method callingMethod = callingClass.getMethod( callingMethodName );
Or even:
Class callingClass = Class.forName( callingClassName );
Method callingMethod = callingClass.getMethod( callingMethodName, null );
I get a NoSuchMethodException. Am I doing something wrong here? Should I be taking a different approach altogether?
In this particular situation, the calling class/method never uses polymorphism so there is only ever 1 signature. However, said signature is not known (unless that can also be determined by data available/derivable from Thread.currentThread( )), so I need a way to get a Method object without knowing the signature.
No. The signature matters. If you don’t know the exact signature, but know the name, get all the methods and iterate over them until you get a hit:
Also, since java 1.5,
Class.getMethod(String, Class...)is a varargs method, so you don’t need the java cruft that both the question and other answer has, ie:This works, but avoid this crap (the old, hard way):
Prefer this (new way):