如何在java中获取方法的字符串名称?

时间:2010-06-11 13:59:07

标签: java reflection

如何通过反射找出该方法的字符串名称?

例如:

class Car{
   public void getFoo(){
   }
}

我想获取字符串“getFoo”,如下所示:

 Car.getFoo.toString() == "getFoo" // TRUE

7 个答案:

答案 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版本执行此操作可能会比较棘手...