使用Java新功能StackWalker

StackWalking API是最近添加到Java中的最酷功能之一

在Java9之前,要获得栈信息办法是:获取当前线程并调用其getStackTrace()方法

StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();

另一个智能解决方案涉及...抛出异常并从中提取堆栈跟踪信息。但是,无法操纵结果,它只会立即输出:

newException().printStackTrace();

两种解决方案都存在同样的问题 - 它们只是捕获了整个堆栈的快照,并且不方便使用。

JEP-259 提出Stack-Walking API可以解决这些问题。新的API提供了一种使用Stream API惰性地遍历堆栈跟踪的便捷方法。

我们可以像以下一样轻松创建StackWalker实例:

StackWalkerstack = StackWalker.getInstance();

还可以定制一点初始化信息:

StackWalkerstack = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);

如果我们想要遍历整个堆栈,只需调用forEach()方法:

stack.forEach(System.out::println);

如果我们查看Java 1.4的StackTraceElement - 它几乎是一个包含有关声明类,方法名,类加载器名等的字符串信息的DTO。

StackWalker.StackFrame是一个更加类型安全友好的升级,丰富了以下方法:

public Class getDeclaringClass();

public MethodType getMethodType();

public StackTraceElement toStackTraceElement();

让我们将其付诸实践并创建一个简单的调用层次结构:

public static voidmain(String[] args){

foo();

}

private static voidfoo(){

bar();

}

private static voidbar(){

java.lang.StackWalker

.getInstance(java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE)

.forEach(System.out::println);

}

运行这段代码获得:

com.pivovarit.stack.StackWalker.bar(StackWalker.java:16)com.pivovarit.stack.StackWalker.foo(StackWalker.java:10)com.pivovarit.stack.StackWalker.main(StackWalker.java:6)

高级功能

如果我们想利用懒加载或frame过滤,我们可以使用另一个名为walk()的专用API方法,它允许我们使用Stream API来方便地遍历堆栈。在阅读本文时,您可能想象walk()方法只是返回一个Stream实例 - 嗯,事实并非如此。

这个方法实际是:

publicTwalk(FunctionsuperStream, ?extendsT>function)

使用基于Function接口的模板方法是有意义的:当调用walk()方法时,堆栈需要被冻结才能遍历它。

我们可以优雅地跳过一些frame,并选择第一个遇到的frame:

java.lang.StackWalker

.getInstance(java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE)

.walk(s -> s.skip(1).limit(1).collect(Collectors.toList()))

.forEach(System.out::println);

// result

com.pivovarit.stack.StackWalker.foo(StackWalker.java:12)

转:https://www.tuicool.com/articles/InAf6vb

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Stackwalker 是一个调试工具,用于获取程序运行时的函数调用栈信息。它可以帮助开发人员快速定位程序中的问题,并提供更好的调试体验。 Stackwalker 可以在 C++ 等编程语言中使用,并且可以跨平台使用。一些常见的 Stackwalker 实现包括 StackWalk64 和 StackTrace。 ### 回答2: Stackwalker是一个用于跟踪程序运行时调用栈的工具。在软件开发中,调用栈对于排查和调试问题是非常重要的。调用栈可以显示程序在执行过程中被调用的函数和它们之间的关系。 Stackwalker能够帮助开发人员获取调用栈的信息,这对于分析程序中的错误和异常非常有帮助。它可以显示每个函数的地址和函数调用的顺序,帮助开发人员跟踪代码的执行路径。 Stackwalker可以通过一些调试技术来实现。例如,在C/C++程序中,可以使用调试器的接口来获取调用栈的信息。通过调试器,Stackwalker可以获得函数和地址的信息,并将它们按照调用顺序组织起来。 使用Stackwalker可以帮助开发人员定位问题的根源。当程序发生错误或崩溃时,开发人员通过查看调用栈的信息,可以确定是哪个函数调用出了问题,从而更快地定位和修复错误。 总之,Stackwalker是一个很有用的工具,可以帮助开发人员追踪程序在运行时的调用栈信息。它对于排查和解决问题非常有帮助,提高了代码调试和分析的效率和准确性。 ### 回答3: StackWalker是一个用于跟踪程序运行过程中调用栈的工具。在程序执行时,每个函数调用都会在调用栈中生成一个帧,记录了该函数的调用信息和局部变量等。StackWalker可以通过遍历调用栈来获取每个帧的信息,从而实现对调用栈的分析和跟踪。 使用StackWalker可以在程序运行时获取当前线程的调用栈,并输出调用栈信息。这对于调试程序中的错误非常有帮助,可以帮助开发人员确定错误发生的位置以及函数的调用路径。通过分析调用栈,还可以检查函数的调用关系,帮助开发人员理解程序的执行流程和调用顺序。 StackWalker可以用于不同编程语言和平台。在C++中,可以通过调用StackWalker提供的接口来获取调用栈信息。StackWalker提供了一些方法,如GetCurrentStackTrace()用于获取当前线程的调用栈;GetCallstackEntry()用于获取指定帧的调用信息等。通过使用这些方法,可以实现对调用栈的遍历和分析。 总而言之,StackWalker是一个方便的工具,能够帮助开发人员在程序运行时跟踪调用栈,并获取调用栈的相关信息。它在程序调试和错误定位中起到了重要的作用,对于分析程序的执行流程和调用关系非常有帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值