スタックトレース - 1

「こんにちは! 今日はスタック トレースとは何なのかを説明します。しかしその前に、スタックとは何なのかを説明する必要があります。」

「特定の従業員への指示である書類の山を想像してください。山の一番上に新しいタスクを置くことも、一番上からタスクを取り出すこともできます。これは、タスクが受け取った順序で実行されるわけではないことを意味します。最後にパイルに置かれたタスクが最初に実行されます。このようにコレクションの要素を構造化すると、スタックが形成されます。

" Java には、そのための特別なコレクションがあります – Stack。これは、「要素を追加」および「要素を取得 (取得)」するメソッドを持つコレクションです。ご想像のとおり、最後に追加された要素が最初に追加されます。取られます。"

「かなり単純に聞こえますね。」

「わかりました。スタック トレースとは何かを説明します。」

「Java プログラムで、メソッド Aがメソッド Bを呼び出し、メソッドB がメソッドCを呼び出し、さらにメソッド D が呼び出されたとします。メソッド Bを終了するには、まずメソッド Cを終了する必要があり、そのためには、まずメソッド Dを終了する必要があります。これは動作はスタックに似ています。」

「なぜ似ていると言えるのですか?」

「たとえば、書類の山の真ん中にあるタスクに到達するには、まずその上にあるすべてのタスクを実行する必要があります。」

「似ているところはありますが、すべてを正しく理解しているかどうかはわかりません。」

「ほら、スタックとは要素の集合です。紙を山に積んだようなものです。上から 3 枚目の紙を取り出すには、まず 2 枚目の紙を取り、そのためには 1 枚目の紙を取り出す必要があります。紙はいつでも出し入れできますが、常に一番上の紙を最初に取らなければなりません。」

「関数呼び出しについても同様です。メソッド Aがメソッド Bを呼び出し、メソッドBがメソッド Cを呼び出します。 Aを終了するには、まずBを終了する必要があり、そのためにはCを終了する必要があります。」

「待ってください。あなたの言っていることを理解できれば、スタックの概念全体は要約すると、「最後に追加された紙片を取得する」と「最後に入力したメソッドからのみ終了できる」ということになります。それは正確ですか? 」

「はい。一連の関数呼び出しは、「呼び出しスタック」または単に「スタック」として知られています。最後に呼び出された関数が、最初に終了する関数です。例を詳しく見てみましょう。」

現在のコールスタックを取得して表示します。
public class ExceptionExample
{
  public static void main(String[] args)
  {
    method1();
  }

  public static void method1()
  {
    method2();
  }

  public static void method2()
  {
    method3();
  }

  public static void method3()
  {
     StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
    for (StackTraceElement element : stackTraceElements)
    {
       System.out.println(element.getMethodName());
    }
  }
}
結果:
getStackTrace
method3
method2
method1
main

「わかりました。関数呼び出しについてはすべて理解しました。しかし、この StackTraceElement とは何ですか?」

「Java マシンはすべての関数呼び出しを追跡します。そのために、Java マシンには特別なコレクション、つまりスタックがあります。ある関数が別の関数を呼び出すと、Java マシンは新しい StackTraceElement オブジェクトをスタックに置きます。関数が終了すると、その要素は削除さますこれは、スタックには「関数呼び出しのスタック」の現在の状態に関する最新の情報が常に保存されることを意味します。

「各StackTraceElementオブジェクトには、呼び出されたメソッドに関する情報が含まれています。特に、メソッド名はgetMethodNameメソッドを使用して取得できます。」

「上の例でこれがどのように機能するかがわかります。

1) コールスタックを取得します。

2) for-eachループを使用して処理します。それが何であるかを忘れていないことを願っています。

3) メソッド名をSystem.outに出力します。

「興味深いですね! それに、それほど複雑ではありません。ありがとう、リシ!」