1. スタックトレースの取得
Java プログラミング言語は、プログラマがプログラム内で何が起こっているかに関する情報を取得するためのさまざまな方法を提供します。言葉だけではありません。
たとえば、C++ プログラムはコンパイルされると、マシン コードが詰まった 1 つの大きなファイルになります。実行時にプログラマが利用できるのは、現在実行中のマシン コードを含むメモリ ブロックのアドレスだけです。それほど多くはないと言えます。
しかし、Java の場合、プログラムがコンパイルされた後でも、クラスはクラスのままであり、メソッドと変数は消えず、プログラマはプログラム内で何が起こっているかに関する情報を取得する多くの方法を持っています。
スタックトレース
たとえば、プログラムの実行中の時点で、現在実行されているメソッドのクラスと名前を確認できます。1 つのメソッドだけではなく、現在のメソッドからそのメソッドに戻るメソッド呼び出しのチェーン全体に関する情報を取得できますmain()
。
現在のメソッド、そのメソッドを呼び出したメソッド、そのメソッドを呼び出したメソッドなどから構成されるリストを スタック トレース と呼びます。次のステートメントで取得できます。
StackTraceElement[] methods = Thread.currentThread().getStackTrace();
2 行で記述することもできます。
Thread current = Thread.currentThread();
StackTraceElement[] methods = current.getStackTrace();
currentThread()
クラスの静的メソッドは、現在のスレッド、つまり現在の実行スレッドに関する情報を含むオブジェクトThread
への参照を返しますThread
。スレッドの詳細については、 Java Coreクエストのレベル 17 と 18 で学習します。
このThread
オブジェクトにはメソッドがありgetStackTrace()
、オブジェクトの配列を返しますStackTraceElement
。各オブジェクトにはメソッドに関する情報が含まれています。これらすべての要素をまとめると、スタック トレースが形成されます。
例:
コード |
---|
|
コンソール出力 |
|
この例のコンソール出力からわかるように、getStackTrace()
メソッドは 3 つの要素の配列を返しました。
getStackTrace()
Thread
クラスのメソッドtest()
Main
クラスのメソッドmain()
Main
クラスのメソッド
このスタック トレースから、次のことが結論付けられます。
- このメソッドは、Main.java ファイルの 11 行目のメソッド
Thread.getStackTrace()
によって呼び出されました。Main.test()
- このメソッドは、Main.java ファイルの 5 行目のメソッド
Main.test()
によって呼び出されました。Main.main()
- 誰も
Main.main()
メソッドを呼び出しませんでした。これは一連の呼び出しの最初のメソッドです。
ちなみに、画面に表示されたのは入手可能な情報の一部のみです。StackTraceElement
それ以外はすべてオブジェクトから直接取得できます
2.StackTraceElement
その名前が示すように、このクラスはスタック トレース要素、つまり .html 内の 1 つのメソッドStackTraceElement
に関する情報を格納するために作成されました。stack trace
このクラスには次のインスタンス メソッドがあります。
方法 | 説明 |
---|---|
|
クラスの名前を返します |
|
メソッドの名前を返します |
|
ファイルの名前を返します (1 つのファイルに複数のクラスを含めることができます) |
|
メソッドが呼び出されたファイル内の行番号を返します。 |
|
モジュールの名前を返します (これは の場合がありますnull )。 |
|
モジュールのバージョンを返します (これは の可能性がありますnull )。 |
これらは、現在の呼び出しスタックに関するより完全な情報を取得するのに役立ちます。
コード | コンソール出力 | ノート |
---|---|---|
|
|
クラス名 メソッド名 ファイル名 行 番号 モジュール名 モジュールバージョン クラス名 メソッド名 ファイル名 行番号 モジュール名 モジュールバージョン クラス名 メソッド名 ファイル名 行 番号 モジュール名 モジュールバージョン |
3. 積み重ねる
スタック トレースが何であるかはすでにわかりましたが、スタック(スタック クラス) とは何でしょうか?
スタックは、要素を追加したりそこから要素を取得したりできるデータ構造です。その際、要素は末尾からのみ取得できます。まず最後に追加された要素を取得し、次に最後から 2 番目に追加された要素を取得します。
名前スタック自体は、紙の束をどのように操作するかのように、この動作を示唆しています。シート 1、2、および 3 をスタックに置いた場合は、逆の順序で取り出す必要があります。最初に 3 番目のシート、次に 2 番目のシート、そして最初のシートだけを取り出す必要があります。
Java には、同じ名前と動作を持つ特別な Stack コレクション クラスもあります。このクラスは多くの動作を およびArrayList
と共有しますLinkedList
。ただし、スタック動作を実装するメソッドもあります。
メソッド | 説明 |
---|---|
|
obj 要素をスタックの先頭に追加します |
|
スタックの最上位から要素を取得します (スタックの深さが減少します)。 |
|
スタックの先頭にある項目を返します (スタックは変更されません)。 |
|
コレクションが空かどうかを確認します |
|
コレクション内のオブジェクトを検索し、そのオブジェクトを返します。index |
例:
コード | スタックの内容 (スタックの一番上が右側) |
---|---|
|
|
スタックはプログラミングでよく使用されます。ということで、これは便利なコレクションです。
4. 例外処理時のスタックトレースの表示
メソッド呼び出しのリストがスタック トレースと呼ばれるのはなぜですか? なぜなら、メソッドのリストをメソッド名が記載された紙の束と考えると、次のメソッドを呼び出すときに、そのメソッドの名前が記載されたシートがスタックに追加されるからです。そして次の紙がその上に置かれ、というように続きます。
メソッドが終了すると、スタックの一番上のシートが削除されます。スタックの中央からシートを削除するには、その上にあるシートをすべて削除する必要があります。同様に、呼び出したすべてのメソッドを終了することなく、一連の呼び出しの途中でメソッドを終了することはできません。
例外
スタックのもう 1 つの興味深い用途は、例外処理時です。
プログラムでエラーが発生し、例外がスローされると、例外には現在のスタック トレースが含まれます。このスタック トレースは、メイン メソッドから始まり、エラーが発生したメソッドで終わるメソッドのリストで構成されます。例外がスローされた行もあります。
このスタック トレースは例外内に保存され、次のメソッドを使用して例外から簡単に取得できます。StackTraceElement[] getStackTrace()
例:
コード | ノート |
---|---|
|
例外をキャッチする エラーが発生したときに存在していたスタック トレースを取得します。 |
これはクラスのメソッドであるThrowable
ため、そのすべての子孫 (つまり、すべての例外) がこのgetStackTrace()
メソッドを持ちます。すごく便利ですね。
例外のスタック トレースを表示する
ちなみに、このThrowable
クラスにはスタック トレースを操作するための別のメソッドがあります。これは、例外内に格納されているすべてのスタック トレース情報を表示するメソッドです。と呼ばれますprintStackTrace()
。
非常に便利なことに、どの例外でも呼び出すことができます。
例:
コード |
---|
|
コンソール出力 |
|
GO TO FULL VERSION