如何使用Java中的StackWalker API打印不同的堆栈帧?
Java 9 定义了一个StackWalkerAPI,它提供惰性和帧过滤。 StackWalker对象允许我们遍历和访问堆栈,并包含一个有用的方法:walk()。此方法为当前线程打开一个StackFrame流,然后将该函数应用于该StackFrame流。我们需要获取StackWalker对象,然后使用StackWalker.getInstance()方法。
在下面的示例中,我们可以打印不同的内容堆栈帧:所有堆栈帧、跳过某些堆栈帧以及使用StackWalkerAPI 限制堆栈帧。 p>
示例
import java.lang.StackWalker.StackFrame; import java.util.*; import java.util.stream.*; public class StackWalkerTest { public static void main(String args[]) { new StackWalkerTest().walk(); } private void walk() { new Walker1().walk(); } private class Walker1 { public void walk() { new Walker2().walk(); } } private class Walker2 { public void walk() { Method1(); } void Method1() { Method2(); } void Method2() { StackWalker stackWalker = StackWalker.getInstance(Set.of(StackWalker.Option.RETAIN_CLASS_REFERENCE, StackWalker.Option.SHOW_HIDDEN_FRAMES), 16); Stream stackStream = StackWalker.getInstance().walk(f -> f); System.out.println("--- Walk all StackFrames ---"); List stacks = walkAllStackframes(); System.out.println(stacks); System.out.println("--- Skip some StackFrames ---"); List stacksAfterSkip = walkSomeStackframes(3); System.out.println(stacksAfterSkip); System.out.println("--- Limit StackFrames ---"); List stacksByLimit = walkLimitStackframes(3); System.out.println(stacksByLimit); } private List walkAllStackframes() { return StackWalker.getInstance().walk(s -> s.map(frame -> "n" + frame.getClassName() + "/" + frame.getMethodName()).collect(Collectors.toList())); } private List walkSomeStackframes(int numberOfFrames) { return StackWalker.getInstance().walk(s -> s.map(frame -> "n" + frame.getClassName() + "/" + frame.getMethodName()).skip(numberOfFrames).collect(Collectors.toList())); } private List walkLimitStackframes(int numberOfFrames) { return StackWalker.getInstance().walk(s -> s.map(frame -> "n" + frame.getClassName() + "/" + frame.getMethodName()).limit(numberOfFrames).collect(Collectors.toList())); } } }登录后复制