walk
メソッドは、現在のスレッドに対してStackFrame
の順次ストリームを開き、指定された関数を適用してStackFrame
ストリームを調査します。 ストリームは、スタックが生成された実行ポイントを表す最上位のフレームから最下位のフレームまで、スタック・フレーム要素を順番にレポートします。 walk
メソッドが戻ると、StackFrame
ストリームは閉じられます。 クローズしたストリームを再利用しようとすると、IllegalStateException
がスローされます。
「スタック・ウォーカ・オプション」は、StackWalker
によって取得されるスタック・フレーム情報を構成します。 デフォルトでは、クラス名とメソッド情報は収集されますが、Class reference
は収集されません。 メソッド情報は、DROP_METHOD_INFO
オプションを使用して削除できます。 Class
オブジェクトは、RETAIN_CLASS_REFERENCE
オプションを使用してアクセスするために保持できます。 リフレクションAPIおよび実装クラスのスタック・フレームは、デフォルトではhiddenです。
StackWalker
はスレッド・セーフです。 複数のスレッドが単一のStackWalker
オブジェクトを共有して、独自のスタックを横断できます。 権限チェックは、リクエストするオプションに従って、StackWalker
の作成時に実行されます。 スタック・ウォーキング時にこれ以上の権限チェックは行われません。
- APIのノート:
- 例
1. 最初の呼び出し元が既知の実装クラスのリストをフィルタリングして検索するには:
StackWalker walker = StackWalker.getInstance(Set.of(Option.DROP_METHOD_INFO, Option.RETAIN_CLASS_REFERENCE)); Optional<Class<?>> callerClass = walker.walk(s -> s.map(StackFrame::getDeclaringClass) .filter(Predicate.not(implClasses::contains)) .findFirst());
2. 現在のスレッドの上位10スタック・フレームのスナップショットを作成するには、
List<StackFrame> stack = StackWalker.getInstance().walk(s -> s.limit(10).toList());
StackWalker
クラスのコンストラクタまたはメソッドにnull
引数を渡すと、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 options
- 戻り値:
- 指定されたオプションで構成された
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のノート:
- たとえば、最初の10個の呼び出しフレームを検索するには、最初に宣言クラスがパッケージ
com.foo
内にあるフレームをスキップします:List<StackFrame> frames = StackWalker.getInstance().walk(s -> s.dropWhile(f -> f.getClassName().startsWith("com.foo.")) .limit(10) .toList());
このメソッドは、
Stream<StackFrame>
を返し、呼出し側がストリームを直接操作できるようにするのではなく、Function
を使用してStream<StackFrame>
を受け入れます。 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(Set.of(Option.DROP_METHOD_INFO, 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());
java
ランチャによって起動されたstatic public void main
メソッドや、JNIアタッチされたスレッドから起動されたメソッドなど、スタックの最下位フレームであるメソッドからgetCallerClass
メソッドがコールされると、IllegalCallerException
がスローされます。 - 戻り値:
- このメソッドを呼び出す呼出し側のコール元の
Class
オブジェクト。 - 例外:
UnsupportedOperationException
- このStackWalker
がOption.RETAIN_CLASS_REFERENCE
で構成されていない場合。IllegalCallerException
- 呼出し側フレームがない場合、つまり、スタックの最後のフレームであるメソッドからこのgetCallerClass
メソッドが呼び出された場合。
-