I'm looking for a convenient workaround for getting the Method object from a method. The idea:
Method fooMethod = getMethod( new MyObject().foo() ) // returns method "foo" in MyObject
The obvious way is to use the name of the method as a string:
Method fooMethod = MyObject.class.getMethod("foo")
but I want to avoid this because if I rename foo() that code will stop working or I have rename the string in all the places where it is used.
The use case is that I want to use something similar to ProperyChangeListeners however those rely on the method name as string. I'd like to use the actual method (safely) and not rely on strings.
What could I use to get the method in a rename safe way?
UPDATE: I'd like to find a pure java solution that does not rely on IDE features
You might want to use annotations. You can create a custom annotation for each method that you want to retrieve and the using reflection pull that method from the object.
You can safely rename the method and your code will work.
If you want to be able to retrieve many methods then use only one annotation with a string value which will change per method and then your reflection code will look for those annotations with that string value. You can still rename your method as long as you leave the string value of the annotation the same.
The safest thing is to use an IDE with refactoring capability that's smart enough to recognize and replace that String method name. IntelliJ from JetBrains does it - I just proved it to myself.
You can use IDE refactoring which take care about all string occurences as well.
You cannot reference a method using reflection otherwise than by its name.
Java 8 method references would be ideal for this - the tricky part is getting to the underlying method, because the method reference syntax itself results in an opaque lambda object.
Found this after a bit of searching:
http://benjiweber.co.uk/blog/2013/12/28/typesafe-database-interaction-with-java-8/
Neat trick - call the method on a proxy object that records the method name. Haven't tried it but looks promising.
In your method call: Method me = (new MethodNameHelper(){}).getMethod();
We have published the small library de.cronn:reflection-util that can be used to capture a method.
Example:
Implementation details: A Proxy subclass of
MyClass
is created with ByteBuddy and a call to the method is captured to retrieve its name.ClassUtils
caches the information such that we do not need to create a new proxy on every invocation.