如何通过反射找出该方法的字符串名称?
例如:
class Car{
public void getFoo(){
}
}
我想获取字符串“getFoo”,如下所示:
Car.getFoo.toString() == "getFoo" // TRUE
答案 0 :(得分:35)
您可以像这样获取字符串:
Car.class.getDeclaredMethods()[0].getName();
这适用于您班级中单个方法的情况。如果要遍历所有声明的方法,则必须遍历Car.class.getDeclaredMethods()
返回的数组:
for (Method method : Car.class.getDeclaredMethods()) {
String name = method.getName();
}
如果要查看所有内容,请使用getDeclaredMethods()
,getMethods()
只会返回公开方法。
最后,如果你想看到当前正在执行的方法的名称,你应该使用这个代码:
Thread.currentThread().getStackTrace()[1].getMethodName();
这将获得当前线程的堆栈跟踪,并在其顶部返回方法的名称。
答案 1 :(得分:20)
由于方法本身不是对象,因此它们没有直接属性(就像您期望的JavaScript语言中的第一类函数一样)。
您最接近的就是致电Car.class.getMethods()
Car.class
是一个Class
对象,您可以使用它来调用任何反射方法。
但是,据我所知,一种方法无法识别自己。
答案 2 :(得分:14)
那么,您想获取当前正在执行的方法的名称吗?这是一种有点难看的方式:
Exception e = new Exception();
e.fillInStackTrace();
String methodName = e.getStackTrace()[0].getMethodName();
答案 3 :(得分:1)
试试这个,
import java.lang.reflect.*;
public class DumpMethods {
public static void main(String args[]) {
try {
Class c = Class.forName(args[0]);
Method m[] = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++)
System.out.println(m[i].toString());
} catch (Throwable e) {
System.err.println(e);
}
}
}
答案 4 :(得分:1)
查看此线程:
Getting the name of the currently executing method
它提供了更多解决方案-例如:
String name = new Object(){}.getClass().getEnclosingMethod().getName();
答案 5 :(得分:0)
等等,既然您已经知道方法名称,那么您不能只将其键入字符串吗?
而不是(伪)Class.methodName.toString()
,只需使用"methodName
“。
否则,您可以使用Class#getDeclaredMethods()
获取类中的所有方法
答案 6 :(得分:0)
使用Java 8,您可以用几行代码(几乎)执行此操作,而无需任何其他库。关键是将您的方法转换为可序列化的lambda表达式。因此,您只需定义一个简单的接口,如下所示:
@FunctionalInterface
public interface SerializableFunction<I, O> extends Function<I, O>, Serializable {
// Combined interface for Function and Serializable
}
现在,我们需要将lambda表达式转换为SerializedLambda
对象。显然,Oracle并不是真的希望我们这样做,因此请一筹莫展...由于所需的方法是私有的,因此我们需要使用反射来调用它:
private static final <T> String nameOf(SerializableFunction<T, ?> lambda) {
Method findMethod = ReflectionUtils.findMethod(lambda.getClass(), "writeReplace");
findMethod.setAccessible(true);
SerializedLambda invokeMethod = (SerializedLambda) ReflectionUtils.invokeMethod(findMethod, lambda);
return invokeMethod.getImplMethodName();
}
为简单起见,我在这里使用Springs ReflectionUtils
类,但是您当然可以通过手动循环所有超类并使用getDeclaredMethod
查找writeReplace
方法来替换它。
已经是它了,现在您可以像这样使用它:
@Test
public void testNameOf() throws Throwable {
assertEquals("getName", nameOf(MyClassTest::getName));
}
我还没有在Java 9s模块系统上进行过检查,因此,作为免责声明,使用最新的Java版本执行此操作可能会比较棘手...