我正在寻找从方法中获取Method对象的便捷解决方法。想法:
Method fooMethod = getMethod( new MyObject().foo() ) // returns method "foo" in MyObject
显而易见的方法是将方法的名称用作字符串:
Method fooMethod = MyObject.class.getMethod("foo")
但是我想避免这种情况,因为如果我重命名foo()代码将停止工作,或者我在所有使用它的地方重命名字符串。
用例是我想使用类似于ProperyChangeListeners的东西,但是那些依赖于方法名称作为字符串。我想使用实际的方法(安全)而不依赖于字符串。
我可以用什么方法以重命名安全的方式获取方法?
更新: 我想找到一个不依赖IDE功能的纯java解决方案
答案 0 :(得分:11)
Java 8方法引用对于此非常理想 - 棘手的部分是获取底层方法,因为方法引用语法本身会导致不透明的lambda对象。
经过一番搜索后发现了这个:
http://benjiweber.co.uk/blog/2013/12/28/typesafe-database-interaction-with-java-8/
巧妙的技巧 - 在记录方法名称的代理对象上调用方法。没试过,但看起来很有希望。
答案 1 :(得分:9)
在您的方法调用中: 方法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();
}
}
答案 2 :(得分:7)
实际上有一个库可以做到这一点:
Jodd MethRef - 强类型方法名称引用
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'
答案 3 :(得分:4)
我们发布了可用于捕获方法的小型库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
的代理子类,并捕获对该方法的调用以检索其名称。
ClassUtils
缓存信息,以便我们不需要在每次调用时创建新代理。
答案 4 :(得分:3)
您可能想要使用注释。您可以为要检索的每个方法创建自定义注释,并使用反射从对象中提取该方法。
您可以安全地重命名该方法,您的代码也可以使用。
如果您希望能够检索许多方法,那么只使用一个带有字符串值的注释,该值将根据方法更改,然后您的反射代码将查找具有该字符串值的注释。只要保留注释的字符串值相同,您仍然可以重命名方法。
答案 5 :(得分:1)
最安全的做法是使用具有重构功能的IDE,该功能足以识别和替换String方法名称。来自JetBrains的IntelliJ做到了 - 我只是向自己证明了这一点。
答案 6 :(得分:-1)
您可以使用IDE重构,它也会关注所有字符串的出现。
除了名称之外,您不能使用反射来引用方法。
答案 7 :(得分:-1)