1. Overview
1.概述
Sometimes we need to know the name of the current Java method being executed.
有时我们需要知道当前正在执行的Java方法的名称。
This quick article presents a couple of simple ways of getting hold of the method name in the current execution stack.
这篇文章介绍了几个简单的方法来掌握当前执行栈中的方法名称。
2. Java 9: Stack-Walking API
2.Java 9:堆栈行走的API
Java 9 introduced the Stack-Walking API to traverse the JVM stack frames in a lazy and efficient manner. In order to find the currently executing method with this API, we can write a simple test:
Java 9引入了Stack-Walking API,以一种懒惰而高效的方式遍历JVM堆栈框架。为了利用该API找到当前正在执行的方法,我们可以编写一个简单的测试。
public void givenJava9_whenWalkingTheStack_thenFindMethod() {
StackWalker walker = StackWalker.getInstance();
Optional<String> methodName = walker.walk(frames -> frames
.findFirst()
.map(StackWalker.StackFrame::getMethodName));
assertTrue(methodName.isPresent());
assertEquals("givenJava9_whenWalkingTheStack_thenFindMethod", methodName.get());
}
First, we get a StackWalker instance using the getInstance() factory method. Then we use the walk() method to traverse the stack frames from the top to the bottom:
首先,我们使用StackWalker工厂方法获得一个getInstance()实例。然后我们使用walk() 方法来从顶部到底部遍历堆栈框架:
- The walk() method can convert a stream of stack frames — Stream<StackFrame> — to anything
- The first element in the given stream is the top frame on the stack
- The top frame on the stack always represents the currently executing method
Therefore, if we get the first element from the stream, we’ll know the currently executing method details. More specifically, we can use StackFrame.getMethodName() to find the method name.
因此,如果我们从流中获得第一个元素,我们就会知道当前执行的方法的细节。更具体地说,我们可以使用StackFrame.getMethodName()来查找方法名称。。
2.1. Advantages
2.1.优势
Compared to other approaches (more on them later), the Stack-Walking API has a few advantages:
与其他方法相比(后面会详细介绍),Stack-Walking API有几个优点。
- No need to create a dummy anonymous inner class instance — new Object().getClass() {}
- No need to create a dummy exception — new Throwable()
- No need to eagerly capture the whole stacktrace, which can be costly
On the contrary, the StackWalker only walks the stack one by one in a lazy fashion. In this case, it only fetches the top frame, as opposed to the stacktrace approach which captures all the frames eagerly.
相反,StackWalker只以一种懒惰的方式一个一个地走过堆栈。在这种情况下,它只抓取最上面的一帧,而不是像堆栈跟踪那样急切地抓取所有的帧。
The bottom line is, use the Stack-Walking API if you’re on Java 9+.
底线是,如果你是在Java 9以上版本,请使用Stack-Walking API。
3. Using getEnclosingMethod
3.使用getEnclosingMethod
We can find the name of the method being executed by using the getEnclosingMethod() API:
我们可以通过使用getEnclosingMethod() API找到正在执行的方法的名称。
public void givenObject_whenGetEnclosingMethod_thenFindMethod() {
String methodName = new Object() {}
.getClass()
.getEnclosingMethod()
.getName();
assertEquals("givenObject_whenGetEnclosingMethod_thenFindMethod",
methodName);
}
4. Using Throwable Stack Trace
4.使用可抛出堆栈跟踪
Using a Throwable stack trace gives us stack trace with the method currently being executed:
使用Throwable堆栈跟踪可以得到当前正在执行的方法的堆栈跟踪。
public void givenThrowable_whenGetStacktrace_thenFindMethod() {
StackTraceElement[] stackTrace = new Throwable().getStackTrace();
assertEquals(
"givenThrowable_whenGetStacktrace_thenFindMethod",
stackTrace[0].getMethodName());
}
5. Using Thread Stack Trace
5.使用线程堆栈跟踪
Also, the stack trace of a current thread (since JDK 1.5) usually includes the name of the method that is being executed:
另外,当前线程的堆栈跟踪(从JDK 1.5开始)通常包括正在执行的方法的名称。
public void givenCurrentThread_whenGetStackTrace_thenFindMethod() {
StackTraceElement[] stackTrace = Thread.currentThread()
.getStackTrace();
assertEquals(
"givenCurrentThread_whenGetStackTrace_thenFindMethod",
stackTrace[1].getMethodName());
}
However, we need to remember that this solution has one significant drawback. Some virtual machines may skip one or more stack frames. Although this is not common, we should be aware that this can happen.
然而,我们需要记住,这种解决方案有一个明显的缺点。一些虚拟机可能会跳过一个或多个堆栈帧。虽然这并不常见,但我们应该意识到这种情况可能发生。
6. Conclusion
6.结论
In this tutorial, we have presented some examples of how to get the name of the currently executed method. Examples are based on stack traces and the getEnclosingMethod().
在本教程中,我们介绍了一些关于如何获得当前执行的方法的名称的例子。例子是基于堆栈跟踪和getEnclosingMethod()。
As always, you can check out the examples provided in this article over on GitHub. Also, Java 9 examples are available in our Java 9 GitHub module.
一如既往,您可以查看本文在GitHub上提供的示例。此外,在我们的Java 9 GitHub 模块中也有Java 9的例子。