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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3023354/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 15:41:24  来源:igfitidea点击:

How to get string name of a method in java?

javareflection

提问by Andriy Drozdyuk

How can I find out through reflection what is the string name of the method?

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

For example given:

例如给出:

class Car{
   public void getFoo(){
   }
}

I want to get the string "getFoo", something like the following:

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

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

采纳答案by Matt

Since methods aren't objects themselves, they don't have direct properties (like you would expect with first-class functions in languages like JavaScript).

由于方法本身不是对象,因此它们没有直接的属性(就像您对 JavaScript 等语言中的一流函数所期望的那样)。

The closest you can do is call Car.class.getMethods()

你能做的最接近的是打电话 Car.class.getMethods()

Car.classis a Classobject which you can use to invoke any of the reflection methods.

Car.class是一个Class可以用来调用任何反射方法的对象。

However, as far as I know, a method is not able to identify itself.

但是,据我所知,一种方法无法识别自己。

回答by zhy2002

try this,

尝试这个,

 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);
            }
        }
    }

回答by Malcolm

You can get the String like this:

您可以像这样获取字符串:

Car.class.getDeclaredMethods()[0].getName();

This is for the case of a single method in your class. If you want to iterate through all the declared methods, you'll have to iterate through the array returned by Car.class.getDeclaredMethods():

这是针对您的类中的单个方法的情况。如果要遍历所有声明的方法,则必须遍历由 返回的数组Car.class.getDeclaredMethods()

for (Method method : Car.class.getDeclaredMethods()) {
    String name = method.getName();
}

You should use getDeclaredMethods()if you want to view all of them, getMethods()will return only publicmethods.

getDeclaredMethods()如果你想查看所有这些,你应该使用,getMethods()只返回公共方法。

And finally, if you want to see the name of the method, which is executing at the moment, you should use this code:

最后,如果您想查看当前正在执行的方法的名称,您应该使用以下代码:

Thread.currentThread().getStackTrace()[1].getMethodName();

This will get a stack trace for the current thread and return the name of the method on its top.

这将获得当前线程的堆栈跟踪,并在其顶部返回方法的名称。

回答by Bozho

Wait, since you already know the method name, can't you just type it as a string?

等等,既然你已经知道方法名,你就不能把它作为字符串输入吗?

Instead of (pseudo) Class.methodName.toString(), just use "methodName".

而不是 (pseudo) Class.methodName.toString(),只需使用"methodName".

Otherwise you can use Class#getDeclaredMethods()to get all the methods in a class

否则,您可以使用Class#getDeclaredMethods()获取类中的所有方法

回答by Jesper

So, you want to get the name of the currently executing method? Here's a somewhat ugly way to do that:

那么,您想获取当前正在执行的方法的名称吗?这是一种有点丑陋的方法:

Exception e = new Exception();
e.fillInStackTrace();
String methodName = e.getStackTrace()[0].getMethodName();

回答by olivmir

Look into this thread:

看看这个线程:

Getting the name of the currently executing method

获取当前正在执行的方法的名称

It offers some more solutions - for example:

它提供了更多的解决方案 - 例如:

String name = new Object(){}.getClass().getEnclosingMethod().getName();

回答by Jan Gassen

With Java 8, you can do this with a few lines of code (almost) without any additional libraries. The key is to convert your method into a serialisable lambda expression. Therefore, you can just define a simple interface like this:

使用 Java 8,您只需几行代码(几乎)就可以做到这一点,而无需任何额外的库。关键是将您的方法转换为可序列化的 lambda 表达式。因此,您可以像这样定义一个简单的接口:

@FunctionalInterface
public interface SerializableFunction<I, O> extends Function<I, O>, Serializable {
  // Combined interface for Function and Serializable
}

Now, we need to convert our lambda expression into a SerializedLambdaobject. Apparently, Oracle does not really want us to do that, so take this with a grain of salt... As the required method is private, we need to invoke it using reflections:

现在,我们需要将 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();
}

I'm using Springs ReflectionUtilsclass here for simplicity, but you can of course replace this by manually looping through all superclasses and use getDeclaredMethodto find the writeReplacemethod.

ReflectionUtils为简单起见,我在这里使用 Springs类,但您当然可以通过手动循环遍历所有超类getDeclaredMethod来替换它,并使用它来查找writeReplace方法。

And this is it already, now you can use it like this:

就是这样,现在您可以像这样使用它:

@Test
public void testNameOf() throws Throwable {
  assertEquals("getName", nameOf(MyClassTest::getName));
}

I haven't checked this with Java 9s module system, so as a little disclaimer it might be more tricky to do this with more recent Java versions...

我没有用 Java 9s 模块系统检查过这个,所以作为一个小小的免责声明,用更新的 Java 版本来做这件事可能会更棘手......