walk
メソッドは、現在のスレッドのStackFrame
の連続ストリームを開き、与えられた関数を適用してStackFrame
ストリームをウォークします。 ストリームは、スタックが生成された実行ポイントを表す一番上のフレームから一番下のフレームまで、順番にスタック・フレーム要素を報告します。 walk
メソッドが戻ると、StackFrame
ストリームが閉じます。 クローズド・ストリームを再利用しようとすると、IllegalStateException
がスローされます。
StackWalker
の「スタック・ウォーキング・オプション」は、返されるStackFrame
オブジェクトの情報を決定します。 デフォルトでは、リフレクションAPIと実装クラスのスタック・フレームはhiddenであり、StackFrame
にはクラス名とメソッド名がありますが、Class reference
は使用できません。
StackWalker
はスレッド・セーフです。 複数のスレッドは、1つのStackWalker
オブジェクトを共有して、独自のスタックをトラバースできます。 StackWalker
がリクエストされたオプションに応じて、許可チェックが実行されます。 積み重ね歩行時間には、それ以上の許可チェックは行われません。
- APIのノート:
- 例
1.実装クラスの既知のリストをフィルタリングする最初の呼び出し元を見つけるには:
StackWalker walker = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE); Optional<Class<?>> callerClass = walker.walk(s -> s.map(StackFrame::getDeclaringClass) .filter(interestingClasses::contains) .findFirst());
2.現在のスレッドの上位10個のスタック・フレームをスナップショットするには、
特に指定のないかぎり、List<StackFrame> stack = StackWalker.getInstance().walk(s -> s.limit(10).collect(Collectors.toList()));
null
引数をこのStackWalker
クラスのコンストラクタまたはメソッドに渡すと、NullPointerException
がスローされます。 - 導入されたバージョン:
- 9
-
ネストされたクラスのサマリー
ネストされたクラス修飾子と型クラス説明static enum
StackWalker
で取得した「スタック・フレーム」情報を構成するオプション。static interface
StackFrame
オブジェクトは、StackWalker
によって返されるメソッド呼び出しを表します。 -
メソッドのサマリー
修飾子と型メソッド説明void
forEach
(Consumer<? super StackWalker.StackFrame> action) 現在のスレッドのStackFrame
ストリームの各要素に対して、このforEach
メソッドを呼び出すメソッドである、スタックの先頭フレームを走査して、指定されたアクションを実行します。Class<?>
getCallerClass
を呼び出したメソッドを呼び出した呼び出し元のClass
オブジェクトを取得します。static StackWalker
StackWalker
インスタンスを返します。static StackWalker
getInstance
(StackWalker.Option option) 指定されたオプションを持つStackWalker
インスタンスを返します。このインスタンスは、アクセスできるスタック・フレーム情報を指定します。static StackWalker
getInstance
(Set<StackWalker.Option> options) 指定されたoptions
を持つStackWalker
インスタンスを返します。このインスタンスは、アクセス可能なスタック・フレーム情報を指定します。static StackWalker
getInstance
(Set<StackWalker.Option> options, int estimateDepth) 指定されたoptions
を持つStackWalker
インスタンスを返します。このインスタンスは、アクセス可能なスタック・フレーム情報を指定します。<T> T
walk
(Function<? super Stream<StackWalker.StackFrame>, ? extends T> function) 指定された関数を、現在のスレッドのStackFrame
ストリームに適用します。この関数は、このwalk
メソッドを呼び出すメソッドです。
-
メソッドの詳細
-
getInstance
public static StackWalker getInstance() -
getInstance
public static StackWalker getInstance(StackWalker.Option option) 指定されたオプションを持つStackWalker
インスタンスを返します。このインスタンスは、アクセスできるスタック・フレーム情報を指定します。セキュリティ・マネージャが存在し、指定された
option
がOption.RETAIN_CLASS_REFERENCE
である場合、RuntimePermission("getStackWalkerWithClassReference")
のcheckPermission
メソッドを呼び出します。- パラメータ:
option
-stack walking option
- 戻り値:
- 指定されたオプションで構成された
StackWalker
- 例外:
SecurityException
- セキュリティ・マネージャが存在し、そのcheckPermission
メソッドがアクセスを拒否した場合。
-
getInstance
public static StackWalker getInstance(Set<StackWalker.Option> options) 指定されたoptions
を持つStackWalker
インスタンスを返します。このインスタンスは、アクセス可能なスタック・フレーム情報を指定します。 与えられたoptions
が空の場合、このStackWalker
はすべての「隠しフレーム」をスキップするように構成され、「クラス参照」は保持されません。セキュリティ・マネージャが存在し、指定された
options
にOption.RETAIN_CLASS_REFERENCE
が含まれている場合、RuntimePermission("getStackWalkerWithClassReference")
のcheckPermission
メソッドが呼び出されます。- パラメータ:
options
-stack walking option
- 戻り値:
- 指定されたオプションで構成された
StackWalker
- 例外:
SecurityException
- セキュリティ・マネージャが存在し、そのcheckPermission
メソッドがアクセスを拒否した場合。
-
getInstance
public static StackWalker getInstance(Set<StackWalker.Option> options, int estimateDepth) 指定されたoptions
を持つStackWalker
インスタンスを返します。このインスタンスは、アクセス可能なスタック・フレーム情報を指定します。 与えられたoptions
が空の場合、このStackWalker
はすべての「隠しフレーム」をスキップするように構成され、「クラス参照」は保持されません。セキュリティ・マネージャが存在し、指定された
options
にOption.RETAIN_CLASS_REFERENCE
が含まれている場合、RuntimePermission("getStackWalkerWithClassReference")
のcheckPermission
メソッドが呼び出されます。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
ストリームに適用します。この関数は、このwalk
メソッドを呼び出すメソッドです。このメソッドが戻ると、
StackFrame
ストリームが閉じられます。 クローズされたStream<StackFrame>
オブジェクトが再利用されると、IllegalStateException
がスローされます。- APIのノート:
- たとえば、宣言クラスがパッケージ
com.foo
にあるフレームを最初にスキップして最初の10個の呼び出しフレームを検索するには、次のようにします:List<StackFrame> frames = StackWalker.getInstance().walk(s -> s.dropWhile(f -> f.getClassName().startsWith("com.foo.")) .limit(10) .collect(Collectors.toList()));
このメソッドは、
Stream<StackFrame>
を返し、呼び出し元がストリームを直接操作できるようにする代わりに、Stream<StackFrame>
を受け入れるFunction
を取ります。 Java仮想マシンは、例えば、最適化解除を介してスレッド制御スタックを自由に再編成することができます。Function
パラメータを取ることで、このメソッドはスレッド制御スタックの安定したビューを通してスタック・フレームにアクセスすることができます。並列実行は実質的に無効になり、ストリーム・パイプラインの実行は現在のスレッドでのみ発生します。
- 実装上のノート:
- 実装は、スタック歩行に特有のフレームを固定することによってスタックを安定させ、スタック歩行が固定されたフレームの上で実行されることを保証します。 ストリーム・オブジェクトが閉じられたり、再利用されたりすると、
IllegalStateException
がスローされます。 - 型パラメータ:
T
- 「スタック・フレーム」のストリームに関数を適用した結果の型。- パラメータ:
function
- 「スタック・フレーム」のストリームを受け取り、結果を返す関数。- 戻り値:
- 「スタック・フレーム」のストリームに関数を適用した結果。
-
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
オブジェクトを取得します。この
StackWalker
が構成されているSHOW_REFLECT_FRAMES
とSHOW_HIDDEN_FRAMES
オプションにかかわらず、このメソッドは「反射枠」、MethodHandle
、および「隠しフレーム」をフィルタリングします。このメソッドは、呼び出し元のフレームが存在する場合に呼び出される必要があります。 スタックの一番下のフレームから呼び出された場合は、
IllegalCallerException
がスローされます。この
StackWalker
がRETAIN_CLASS_REFERENCE
オプションで構成されていない場合、このメソッドはUnsupportedOperationException
をスローします。- APIのノート:
- たとえば、
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
メソッドが、スタックの一番下のフレームであるメソッドから呼び出されると、java
ランチャによって起動されたstatic public void main
メソッド、またはJNIにアタッチされたスレッドから呼び出されたメソッドIllegalCallerException
がスローされます。 - 戻り値:
Class
このメソッドを呼び出す呼び出し側呼び出し元のオブジェクト。- 例外:
UnsupportedOperationException
- このStackWalker
がOption.RETAIN_CLASS_REFERENCE
で構成されていない場合。IllegalCallerException
- 呼び出し元フレームがない場合、つまりこのgetCallerClass
メソッドがスタック上の最後のフレームであるメソッドから呼び出された場合。
-