作者:昆明DVD导航 | 来源:互联网 | 2024-12-10 05:32
本文探讨了Java9中StackWalkingAPI的一个特性——StackWalker.Option.SHOW_HIDDEN_FRAMES。通过实例分析,揭示了该选项在不同场景下的具体表现及其重要性。
最近我在研究Java 9引入的StackWalking API时遇到了一个问题,即无论是否启用StackWalker.Option.SHOW_HIDDEN_FRAMES选项,输出结果似乎没有明显变化。为了更好地理解这一选项的实际作用,我们来深入探讨一下。
根据官方文档,StackWalker.Option.SHOW_HIDDEN_FRAMES选项允许StackWalker显示所有被隐藏的帧,包括反射帧和其他由JVM实现特定的帧。这意味着,如果启用了这个选项,StackWalker将不仅显示常规的调用栈信息,还会显示那些通常被JVM隐藏的帧,这些帧可能包括但不限于:
- 反射调用帧(例如,通过Method.invoke()或Constructor.newInstance()调用)
- JVM内部实现细节相关的帧
下面是我的测试代码示例,用于展示启用和禁用SHOW_HIDDEN_FRAMES选项时的不同之处:
class DemoClass {
public static void a() {
b();
}
static void b() {
c();
}
static void c() {
d();
}
static void d() {
StackWalker sw = StackWalker.getInstance(Set.of(StackWalker.Option.RETAIN_CLASS_REFERENCE, StackWalker.Option.SHOW_HIDDEN_FRAMES));
sw.forEach(System.out::println);
}
}
public class StackWalkerAPI {
public static void main(String[] args) {
try {
Method methodA = Class.forName("DemoClass").getMethod("a");
methodA.invoke(null, (Object[]) null);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
当运行上述代码时,我们可以观察到启用SHOW_HIDDEN_FRAMES选项后的输出,它不仅显示了标准的方法调用栈,还额外显示了一些通常被隐藏的帧,例如反射调用帧:
internal/experiment.StackWalkerDemo.lambda$d$0(StackWalkerDemo.java:29)
java.base/java.lang.Iterable.forEach(Iterable.java:75)
internal/experiment.StackWalkerDemo.d(StackWalkerDemo.java:28)
internal/experiment.StackWalkerDemo.c(StackWalkerDemo.java:20)
internal/experiment.StackWalkerDemo.b(StackWalkerDemo.java:16)
internal/experiment.StackWalkerDemo.a(StackWalkerDemo.java:12)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base/java.lang.reflect.Method.invoke(Method.java:564)
internal/experiment.StackWalkerAPI.main(StackWalkerAPI.java:15)
从输出可以看到,反射调用的详细信息也被完整地展现出来,这有助于开发者在调试过程中更全面地了解程序的执行流程。此外,还有一些特定于实现的帧(如lambda表达式的调用帧),这些帧在常规情况下是不可见的,但在启用SHOW_HIDDEN_FRAMES后也会被显示出来,这对于深入分析程序行为非常有帮助。