[英]How to get string name of a method in java?
如何通过反射找出方法的字符串名称是什么?
例如给出:
class Car{
public void getFoo(){
}
}
我想获取字符串“ getFoo”,如下所示:
Car.getFoo.toString() == "getFoo" // TRUE
您可以像这样获取字符串:
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();
这将获取当前线程的堆栈跟踪,并在其顶部返回该方法的名称。
由于方法本身不是对象,因此它们没有直接的属性(就像您希望使用JavaScript之类的一流函数那样)。
最接近的方法是调用Car.class.getMethods()
Car.class
是一个Class
对象,可用于调用任何反射方法。
但是,据我所知,一种方法无法识别自己。
那么,您想获取当前正在执行的方法的名称吗? 这是一种难看的方法:
Exception e = new Exception();
e.fillInStackTrace();
String methodName = e.getStackTrace()[0].getMethodName();
尝试这个,
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);
}
}
}
查看此线程:
它提供了更多解决方案-例如:
String name = new Object(){}.getClass().getEnclosingMethod().getName();
使用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版本执行此操作可能会比较棘手...
等等,因为您已经知道方法名称,难道不能只将其键入为字符串吗?
代替(伪) Class.methodName.toString()
,只需使用"methodName
”即可。
否则,您可以使用Class#getDeclaredMethods()
获取类中的所有方法
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.