How to get a Method object in Java without using method line names

I am looking for a convenient workaround to get a Method object from a method. Idea:

Method fooMethod = getMethod( new MyObject().foo() ) // returns method "foo" in MyObject 

The obvious way is to use the method name as a string:

 Method fooMethod = MyObject.class.getMethod("foo") 

but I want to avoid this, because if I rename foo (), this code will stop working or I will rename the string in all places where it is used.

A use case is that I want to use something similar to ProperyChangeListeners , however they rely on the method name as a string. I would like to use the actual method (safely) and not rely on strings.

What can I use to get the method in a safe way of renaming?

UPDATE : I would like to find a pure Java solution that does not rely on IDE functions.

+12
java reflection
Mar 25 2018-12-12T00:
source share
8 answers

There is actually a library that can do this:

Jodd MethRef - Strongly Typed Method Name References

https://jodd.org/ref/methref.html

 Methref<Str> m = Methref.on(Str.class); // create Methref tool // example #1 m.to().boo(); m.ref(); // returns String: 'boo' 
+6
May 03 '14 at 6:10
source share

References to Java 8 methods are ideal for this - the tricky part goes to the base method, since the method syntax itself leads to an opaque lambda object.

Found this after a little search:

http://benjiweber.co.uk/blog/2013/12/28/typesafe-database-interaction-with-java-8/

A neat trick is to call a method on a proxy object that writes the name of the method. I have not tried it, but it looks promising.

+10
Mar 30 '14 at 14:25
source share

In a method call: Method me = (new MethodNameHelper () {}). getMethod ();

 /** * Proper use of this class is * Method me = (new MethodNameHelper(){}).getMethod(); * the anonymous class allows easy access to the method name of the enclosing scope. */ public class MethodNameHelper { public Method getMethod() { return this.getClass().getEnclosingMethod(); } } 
+8
Mar 25 '12 at 22:10
source share

We published a small de.cronn library : reflection-util , which can be used to capture a method.

Example:

 class MyClass { public void myMethod() { } } Method method = ClassUtils.getVoidMethod(MyClass.class, MyClass::myMethod); System.out.println(method.getName()); // prints "myMethod" 

Implementation Details: A subclass of the MyClass routine is created using ByteBuddy , and a method call is captured to retrieve its name. ClassUtils caches information in such a way that we do not need to create a new proxy server with every call.

+4
Nov 15 '17 at 8:42 on
source share

The safest thing is to use an IDE with refactoring capabilities smart enough to recognize and replace this String method name. IntelliJ from JetBrains does this - I just proved it myself.

+2
Mar 25 2018-12-25T00:
source share

You might want to use annotations. You can create a custom annotation for each method that you want to receive, and using reflection, pull this method out of the object.

You can safely rename the method and your code will work.

If you want to get many methods, use only one annotation with a string value, which will be changed for each method, and then the reflection code will look for these annotations with this string value. You can still rename your method as long as you leave the string value of the annotation the same.

+2
Mar 25 '12 at 22:26
source share

You can use IDE refactoring, which also takes care of all string entries.

You cannot reference a method using reflection, except on its name.

0
Mar 25 2018-12-25T00:
source share

Using reflection, you give up security during compilation, simply by nature.

Instead, consider whether reflection is really necessary here. You can submit your method using Runnable , for example:

 Runnable foo = new Runnable() { @Override public void run() { new MyObject().foo(); } } ... foo.run(); 

Or, if you need to introduce a method with a return type, look at Callable - or even better, Guava Function .

0
Mar 25 2018-12-12T00:
source share



All Articles