如何在不使用方法字符串名称的情况下在Java中获取Method对象

我正在寻找一种从方法中获取Method对象的方便的解决方法。 想法:

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

显而易见的方法是将方法的名称用作字符串:

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

但我想避免这种情况,因为如果我重命名foo()代码将停止工作或我在所有使用它的地方重命名字符串。

用例是我想使用类似于ProperyChangeListeners的东西,但是那些依赖于方法名称作为字符串。 我想使用实际的方法(安全)而不依赖于字符串。

我可以使用什么方法以重命名安全的方式获取方法?

更新 :我想找到一个不依赖IDEfunction的纯Java解决方案

Java 8方法引用对于此是理想的 – 棘手的部分是获取底层方法,因为方法引用语法本身导致不透明的lambda对象。

经过一番搜索后发现了这个:

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

干净的技巧 – 在记录方法名称的代理对象上调用方法。 没试过但看起来很有希望。

在你的方法调用中: 方法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(); } } 

实际上有一个库可以做到这一点:

Jodd MethRef – 强类型方法名称参考

http://jodd.org/doc/methref.html

 Methref m = Methref.on(Str.class); // create Methref tool // example #1 m.to().boo(); m.ref(); // returns String: 'boo' 

我们已经发布了可用于捕获方法的小型库de.cronn:reflection-util 。

例:

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

实现细节:使用ByteBuddy创建MyClass的Proxy子类,并捕获对该方法的调用以检索其名称。 ClassUtils缓存信息,以便我们不需要在每次调用时创建新的代理。

最安全的做法是使用具有重构function的IDE,该function足以识别和替换String方法名称。 来自JetBrains的IntelliJ就是这样做的 – 我只是向自己certificate了这一点。

您可能想要使用注释。 您可以为要检索的每个方法创建自定义注释,并使用reflection从该对象中拉出该方法。

您可以安全地重命名该方法,您的代码将起作用。

如果您希望能够检索许多方法,那么只使用一个带有字符串值的注释,该值将根据方法更改,然后您的reflection代码将查找具有该字符串值的注释。 只要保留注释的字符串值相同,您仍然可以重命名方法。

您可以使用IDE重构来处理所有字符串出现。

除了名称之外,您不能使用reflection引用方法。

通过使用reflection,你放弃了编译时的安全性,就其本质而言。

而是考虑这里是否真的需要反思。 您可以使用Runnable表示您的方法,例如:

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

或者,如果您需要使用返回类型表示方法,请查看Callable – 或者更好的是,Guava的Function