クラスStackWalker
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 enumStackWalkerで取得した「スタック・フレーム」情報を構成するオプション。static interfaceStackFrameオブジェクトは、StackWalkerによって返されるメソッド呼び出しを表します。 -
メソッドのサマリー
修飾子と型メソッド説明voidforEach(Consumer<? super StackWalker.StackFrame> action) 現在のスレッドのStackFrameストリームの各要素に対して、このforEachメソッドをコールするメソッドであるスタックのトップ・フレームから移動して、指定されたアクションを実行します。Class<?> getCallerClassを呼び出したメソッドを呼び出した呼び出し元のClassオブジェクトを取得します。static StackWalkerStackWalkerインスタンスを返します。static StackWalkergetInstance(StackWalker.Option option) アクセス可能なスタック・フレーム情報を指定する、指定されたオプションを使用してStackWalkerインスタンスを返します。static StackWalkergetInstance(Set<StackWalker.Option> options) アクセス可能なスタック・フレーム情報を指定する、指定されたoptionsを持つStackWalkerインスタンスを返します。static StackWalkergetInstance(Set<StackWalker.Option> options, int estimateDepth) アクセス可能なスタック・フレーム情報を指定する、指定されたoptionsを持つStackWalkerインスタンスを返します。<T> Twalk(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 optionsestimateDepth- トラバースされるスタック・フレームの推定数。- 戻り値:
- 指定されたオプションで構成された
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メソッドが呼び出された場合。
-