public final class StackWalker extends Object
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 classStackWalker.OptionStackWalkerで取得した「スタック・フレーム」情報を構成するオプション。static interfaceStackWalker.StackFrameStackFrameオブジェクトは、StackWalkerによって返されるメソッド呼び出しを表します。 -
メソッドのサマリー
修飾子と型 メソッド 説明 voidforEach(Consumer<? super StackWalker.StackFrame> action)現在のスレッドのStackFrameストリームの各要素に対して、このforEachメソッドを呼び出すメソッドである、スタックの先頭フレームを走査して、指定されたアクションを実行します。Class<?>getCallerClass()getCallerClassを呼び出したメソッドを呼び出した呼び出し元のClassオブジェクトを取得します。static StackWalkergetInstance()StackWalkerインスタンスを返します。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 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 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のノート:
- たとえば、宣言クラスがパッケージ
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メソッドがスタック上の最後のフレームであるメソッドから呼び出された場合。
-