内容字号:默认大号超大号

段落设置:段首缩进取消段首缩进

字体设置:切换到微软雅黑切换到宋体

使用Java新功能StackWalker

2018-09-11 21:50 出处:清屏网 人气: 评论(0

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

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

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

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

new Exception().printStackTrace();

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

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

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

StackWalker stack = StackWalker.getInstance();

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

StackWalker stack = 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 void main(String[] args) {
    foo();
}

private static void foo() {
    bar();
}

private static void bar() {
    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实例 - 嗯,事实并非如此。

这个方法实际是:

public <T> T walk(Function<? super Stream<StackFrame>, ? extends T> 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)
分享给小伙伴们:
本文标签: StackWalkerJava

相关文章

发表评论愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。

CopyRight © 2015-2016 QingPingShan.com , All Rights Reserved.

清屏网 版权所有 豫ICP备15026204号