是否有一种方法来获得Java中当前正在执行的方法的名称?


当前回答

另一种方法是创建(但不是抛出)一个Exception,并使用该对象从中获取堆栈跟踪数据,因为封闭方法通常位于索引0——只要JVM存储该信息,就像上面其他人提到的那样。然而,这并不是最便宜的方法。

从Throwable.getStackTrace()(这至少从Java 5开始是一样的):

数组的第0个元素(假设数组的长度非零)表示堆栈的顶部,这是序列中的最后一个方法调用。通常,这是这个throwable被创建和抛出的点。

下面的代码片段假设该类是非静态的(因为getClass()),但这只是题外话。

System.out.printf("Class %s.%s\n", getClass().getName(), new Exception("is not thrown").getStackTrace()[0].getMethodName());

其他回答

我使用这个代码片段与最新的Android Studio与最新的Java更新。它可以从任何活动、片段等调用。

public static void logPoint() {
    String[] splitPath = Thread.currentThread().getStackTrace()[3]
        .toString().split("\\.");

    Log.d("my-log", MessageFormat.format("{0} {1}.{2}",
        splitPath[splitPath.length - 3],
        splitPath[splitPath.length - 2],
        splitPath[splitPath.length - 1]
    ));
}

像这样叫它

logPoint();

输出

... D/my-log: MainActivity onCreate[(MainActivity.java:44)]

从技术上讲,这是可行的……

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

但是,在编译时将创建一个新的匿名内部类(例如YourClass$1.class)。这将为每个部署这个技巧的方法创建一个。class文件。此外,在运行时的每次调用上都会创建一个未使用的对象实例。因此,这可能是一个可接受的调试技巧,但它确实带来了巨大的开销。

这种技巧的一个优点是getEnclosingMethod()返回java.lang.reflect.Method,该方法可用于检索方法的所有其他信息,包括注释和参数名。这使得区分具有相同名称的特定方法成为可能(方法重载)。

注意,根据getEnclosingMethod()的JavaDoc,这个技巧不应该抛出SecurityException,因为内部类应该使用相同的类装入器装入。因此,即使有安全管理人员在场,也不需要检查访问条件。

请注意:对于构造函数,必须使用getEnclosingConstructor()。在(命名)方法之外的块中,getEnclosingMethod()返回null。

另一种方法是创建(但不是抛出)一个Exception,并使用该对象从中获取堆栈跟踪数据,因为封闭方法通常位于索引0——只要JVM存储该信息,就像上面其他人提到的那样。然而,这并不是最便宜的方法。

从Throwable.getStackTrace()(这至少从Java 5开始是一样的):

数组的第0个元素(假设数组的长度非零)表示堆栈的顶部,这是序列中的最后一个方法调用。通常,这是这个throwable被创建和抛出的点。

下面的代码片段假设该类是非静态的(因为getClass()),但这只是题外话。

System.out.printf("Class %s.%s\n", getClass().getName(), new Exception("is not thrown").getStackTrace()[0].getMethodName());

要获取调用当前方法的方法的名称,您可以使用:

new Exception("is not thrown").getStackTrace()[1].getMethodName()

这在我的MacBook和我的Android手机上都可以使用

我还试过:

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

但是Android会返回"getStackTrace" 我可以修复这个Android

Thread.currentThread().getStackTrace()[2]

但后来我在笔记本电脑上得到了错误的答案

Thread.currentThread().getStackTrace()通常会包含你调用它的方法,但有陷阱(参见Javadoc):

在某些情况下,一些虚拟机可能会从堆栈跟踪中省略一个或多个堆栈帧。在极端情况下,允许没有关于此线程的堆栈跟踪信息的虚拟机从此方法返回零长度数组。