- java.lang.Object
-
- java.lang.StackWalker
-
public final class StackWalker extends Object
堆栈步行者。walk
方法为当前线程打开StackFrame
s的顺序流,然后应用给定的函数来StackFrame
流。 流从堆栈生成到最底层的执行点的最上面的帧起按顺序报告堆栈帧元素。StackFrame
流程在walk
方法返回时关闭。 如果尝试重新使用封闭流,则将抛出IllegalStateException
。所述stack walking options一个的
StackWalker
确定的信息StackFrame
级要返回的对象。 默认情况下,反射API和实现类的堆栈帧为hidden,而StackFrame
具有可用的类名称和方法名称,但不包括Class reference
。StackWalker
是线程安全的。 多个线程可以共享一个StackWalker
对象来遍历其自己的堆栈。 根据其请求的选项创建StackWalker
时,将执行许可检查。 在堆栈步行时间内不进行进一步的权限检查。- API Note:
-
例子
1.找到第一个调用者过滤一个已知的实现类列表:
StackWalker walker = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE); Optional<Class<?>> callerClass = walker.walk(s -> s.map(StackFrame::getDeclaringClass) .filter(interestingClasses::contains) .findFirst());
2.要快照当前线程的前十个堆栈帧,
List<StackFrame> stack = StackWalker.getInstance().walk(s -> s.limit(10).collect(Collectors.toList()));
null
参数传递给此StackWalker
类中的构造函数或方法将导致抛出NullPointerException
。 - 从以下版本开始:
- 9
-
-
Nested Class Summary
Nested Classes Modifier and Type Class 描述 static class
StackWalker.Option
堆栈步行器选项配置stack frame获取的信息由StackWalker
。static interface
StackWalker.StackFrame
AStackFrame
对象表示由StackWalker
返回的方法调用。
-
方法摘要
所有方法 静态方法 接口方法 具体的方法 Modifier and Type 方法 描述 void
forEach(Consumer<? super StackWalker.StackFrame> action)
对当前线程的StackFrame
流的每个元素执行给定的动作,从堆栈的顶部框架遍历,这是调用此forEach
方法的方法。Class<?>
getCallerClass()
获取调用者调用getCallerClass
的方法的调用者的Class
对象。static StackWalker
getInstance()
返回一个StackWalker
实例。static StackWalker
getInstance(StackWalker.Option option)
返回一个具有给定选项的StackWalker
实例,指定可以访问的堆栈帧信息。static StackWalker
getInstance(Set<StackWalker.Option> options)
返回一个StackWalker
实例,给定的options
指定可以访问的堆栈帧信息。static StackWalker
getInstance(Set<StackWalker.Option> options, int estimateDepth)
返回一个StackWalker
实例,给定的options
指定可以访问的堆栈帧信息。<T> T
walk(Function<? super Stream<StackWalker.StackFrame>,? extends T> function)
将给定的函数应用于当前线程的StackFrame
的流,从堆栈的顶部框架遍历,这是调用此walk
方法的方法。
-
-
-
方法详细信息
-
getInstance
public static StackWalker getInstance()
返回一个StackWalker
实例。这个
StackWalker
被配置为跳过所有hidden frames并且不保留class reference 。- 结果
-
一个
StackWalker
配置为跳过所有 hidden frames ,而不保留 class reference 。
-
getInstance
public static StackWalker getInstance(StackWalker.Option option)
返回一个具有给定选项的StackWalker
实例,指定可以访问的堆栈帧信息。如果存在安全管理员,并且给定的
option
是Option.RETAIN_CLASS_REFERENCE
,则它将其checkPermission
方法RuntimePermission("getStackWalkerWithClassReference")
。- 参数
-
option
-stack walking option
- 结果
-
一个
StackWalker
配置了给定的选项 - 异常
-
SecurityException
- 如果安全管理器存在,并且其checkPermission
方法拒绝访问。
-
getInstance
public static StackWalker getInstance(Set<StackWalker.Option> options)
返回一个StackWalker
实例,给定的options
指定可以访问的堆栈帧信息。 如果给定的options
为空,则此StackWalker
配置为跳过所有hidden frames,并且不保留class reference 。如果存在安全管理员,并且给定的
options
包含Option.RETAIN_CLASS_REFERENCE
,则它将其checkPermission
方法RuntimePermission("getStackWalkerWithClassReference")
。- 参数
-
options
-stack walking option
- 结果
-
一个
StackWalker
配置了给定的选项 - 异常
-
SecurityException
- 如果存在安全管理员,并且其checkPermission
方法拒绝访问。
-
getInstance
public static StackWalker getInstance(Set<StackWalker.Option> options, int estimateDepth)
返回一个StackWalker
实例,给定的options
指定可以访问的堆栈帧信息。 如果给定的options
为空,则此StackWalker
配置为跳过所有hidden frames,并且不保留class reference 。如果存在安全管理员,并且给定的
options
包含Option.RETAIN_CLASS_REFERENCE
,则它将其checkPermission
方法RuntimePermission("getStackWalkerWithClassReference")
。estimateDepth
指定StackWalker
将通过StackWalker
可用作缓冲区大小提示的堆栈帧的估计数。- 参数
-
options
-stack walking options
-
estimateDepth
- 估计要运行的堆栈帧数。 - 结果
-
一个
StackWalker
配置了给定的选项 - 异常
-
IllegalArgumentException
- 如果是estimateDepth <= 0
-
SecurityException
- 如果安全管理器存在,并且其checkPermission
方法拒绝访问。
-
walk
public <T> T walk(Function<? super Stream<StackWalker.StackFrame>,? extends T> function)
将给定的函数应用于当前线程的StackFrame
s的流,从堆栈的顶部框架遍历,这是调用此walk
方法的方法。当此方法返回时,
StackFrame
流将关闭。 当关闭的Stream<StackFrame>
对象被重用时,将抛出IllegalStateException
。- API Note:
-
例如,要查找前10个调用帧,首先跳过声明类在包
com.foo
那些帧:List<StackFrame> frames = StackWalker.getInstance().walk(s -> s.dropWhile(f -> f.getClassName().startsWith("com.foo.")) .limit(10) .collect(Collectors.toList()));
该方法需要
Function
接受Stream<StackFrame>
,而不是返回一个Stream<StackFrame>
并允许调用者直接操纵流。 Java虚拟机可以自由地重组线程的控制堆栈,例如通过去优化。 通过获取一个Function
参数,该方法允许通过线程的控制堆栈的稳定视图访问堆栈帧。有效地禁止并行执行,流管道执行只会在当前线程上发生。
- Implementation Note:
-
该实现通过锚定特定于堆栈行走的框架来稳定堆栈,并确保在锚定框架上执行堆栈行走。
当流对象关闭或重新使用时,将抛出
IllegalStateException
。 - 参数类型
-
T
- 将函数应用于流的结果的类型stack frame 。 - 参数
-
function
- 一个接收stack frames流并返回结果的函数。 - 结果
- 将功能应用于stack frame的流的结果 。
-
forEach
public void forEach(Consumer<? super StackWalker.StackFrame> action)
对当前线程的StackFrame
流的每个元素执行给定的动作,从堆栈的顶部框架遍历,这是调用这个forEach
方法的方法。这个方法相当于调用
walk(s -> { s.forEach(action); return null; });
- 参数
-
action
- 当前线程的堆栈中每个StackFrame
执行的操作
-
getCallerClass
public Class<?> getCallerClass()
获取调用者调用getCallerClass
的方法的调用者的Class
对象。该方法过滤reflection frames ,
MethodHandle
,和hidden frames不管SHOW_REFLECT_FRAMES
个SHOW_HIDDEN_FRAMES
这个选项StackWalker
已配置。当调用者帧存在时,应该调用此方法。 如果从堆栈的最底层调用,将抛出
IllegalCallerException
。如果此
StackWalker
未配置RETAIN_CLASS_REFERENCE
选项,则此方法将抛出UnsupportedOperationException
。- API Note:
-
例如,
Util::getResourceBundle
代表调用者加载资源束。 它调用getCallerClass
来标识其方法叫做Util::getResourceBundle
的类。 然后,它获取该类的类加载器,并使用类加载器加载资源束。 此示例中的调用者类为MyTool
。class Util { private final StackWalker walker = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE); public ResourceBundle getResourceBundle(String bundleName) { Class<?> caller = walker.getCallerClass(); return ResourceBundle.getBundle(bundleName, Locale.getDefault(), caller.getClassLoader()); } } class MyTool { private final Util util = new Util(); private void init() { ResourceBundle rb = util.getResourceBundle("mybundle"); } }
walk
方法查找呼叫者类的方法如下(过滤反射帧,MethodHandle
和隐藏帧,如下所示):Optional<Class<?>> caller = walker.walk(s -> s.map(StackFrame::getDeclaringClass) .skip(2) .findFirst());
getCallerClass
方法是从在堆叠的底部最帧的方法调用,例如,static public void main
方法由推出java
发射器,或从JNI附线程上调用的方法,IllegalCallerException
被抛出。 - 结果
-
调用方调用此方法的对象为
Class
。 - 异常
-
UnsupportedOperationException
- 如果这个StackWalker
没有配置Option.RETAIN_CLASS_REFERENCE
。 -
IllegalCallerException
- 如果没有调用方框,即当从堆栈中最后一帧的方法调用此getCallerClass
方法时。
-
-