ホームページ  >  記事  >  Java  >  Java例外スタックトレースサンプルコードの詳細説明

Java例外スタックトレースサンプルコードの詳細説明

黄舟
黄舟オリジナル
2017-03-17 10:51:331685ブラウズ

この記事では主にJava例外スタックトレース(Stack Trace)の詳しい説明とサンプルコードの関連情報を紹介します

Java例外スタックトレース(Stack Trace)の詳細説明

例外がキャッチされると、多くの場合、何らかの処理が必要になります。より簡単で直接的な方法は、例外スタック トレース Stack Trace を出力することです。スタック トレースといえば、多くの人が私と同じように、最初に printStackTrace() メソッドを思い浮かべるかもしれません。実はこの方法以外にもスタックトレースに関する内容がいくつかあります。

1.printStackTrace()

まず第一に、このメソッドが Exception クラスからのものではないことを明確にする必要があります。いくつかのコンストラクターを定義する Exception クラス自体を除き、すべてのメソッドはその親クラスから継承されます。例外に関連するメソッドはすべて java.lang.Throwable クラスから継承されます。 printStackTrace() もその 1 つです。

このメソッドは、Throwable オブジェクトのスタック トレース情報を標準エラー出力ストリームに出力します。出力の一般的な外観は次のとおりです:

java.lang.NullPointerException
     at MyClass.mash(MyClass.java:9)
     at MyClass.crunch(MyClass.java:6)
     at MyClass.main(MyClass.java:3)

出力の最初の行は toString() メソッドの出力で、次の行の内容は fillInStackTrace() メソッドを通じて以前に保存された内容です。この方法については後ほど説明します。

例を見てみましょう:

public class TestPrintStackTrace {
  public static void f() throws Exception{
    throw new Exception("出问题啦!");
  }
  public static void g() throws Exception{
    f();
  }
  public static void main(String[] args) {
    try {
      g();
    }catch(Exception e) {
      e.printStackTrace();
    }
  }
}

この例の出力は次のとおりです:

java.lang.Exception: 出问题啦!
  at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
  at TestPrintStackTrace.g(TestPrintStackTrace.java:6)
  at TestPrintStackTrace.main(TestPrintStackTrace.java:10)

この例では、メソッド f() で例外がスローされ、メソッド f() がメソッド g() で呼び出され、メソッド f() はメソッド g() で呼び出され、例外をキャッチし、スタック トレース情報を出力します。したがって、出力は f->g->main の処理を​​順番に示します。 2.getStackTrace() メソッド

このメソッドは、printStackTrace() メソッドによって出力される情報へのプログラムによるアクセスを提供します。スタック トレース要素の配列を返します。上記の出力を例にとると、出力行 2 ~ 4 の各行の内容はスタック トレース要素に対応します。これらのスタック トレース要素を配列に保存します。各要素はスタックのスタック フレームに対応します。配列の最初の要素には、スタックの最上位の要素 (f 上) が格納されます。最後の要素によって保存されたスタックの一番下の要素。

以下は、getStackTrace() を使用してこれらのトレース スタック要素にアクセスし、出力を出力する例です。

public class TestPrintStackTrace {
  public static void f() throws Exception{
    throw new Exception("出问题啦!");
  }
  public static void g() throws Exception{
    f();
  }
  public static void main(String[] args) {
    try {
      g();
    }catch(Exception e) {
      e.printStackTrace();
      System.out.println("------------------------------");
      for(StackTraceElement elem : e.getStackTrace()) {
        System.out.println(elem);
      }
    }
  }
}

このような出力は、次のように、printStackTrace() の出力と基本的に同じです。 )

この方法については以前にも説明しました。この方法を明確にするために、まず例外をキャッチした後に再スローする問題について説明する必要があります。 catch コード ブロックで例外をキャッチし、スタック トレースを出力し、再度スローします。前のレベルのメソッド呼び出しで、この例外をキャッチし、スタック トレース情報を出力します。 2 つのスタック トレース情報は同じになりますか?コードを見てみましょう:

java.lang.Exception: 出问题啦!
  at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
  at TestPrintStackTrace.g(TestPrintStackTrace.java:6)
  at TestPrintStackTrace.main(TestPrintStackTrace.java:10)
TestPrintStackTrace.f(TestPrintStackTrace.java:3)
TestPrintStackTrace.g(TestPrintStackTrace.java:6)
TestPrintStackTrace.main(TestPrintStackTrace.java:10)

main メソッドでキャッチされた例外は g() メソッドでスローされます。2 番目のスタック トレースで出力される情報は異なるはずです。 time には f に関する情報が含まれていてはなりません。しかし実際には、2 回出力されたスタック トレース情報は同じです。出力結果は次のとおりです。

public class TestPrintStackTrace {
  public static void f() throws Exception{
    throw new Exception("出问题啦!");
  }
  public static void g() throws Exception{
    try {
      f();
    }catch(Exception e) {
      e.printStackTrace();
      throw e;
    }
     
  }
  public static void main(String[] args) {
    try {
      g();
    }catch(Exception e) {
      e.printStackTrace();
    }
  }
}

つまり、例外がキャッチされてすぐにスローされた場合と、上位メソッド呼び出しで再度例外がキャッチされた場合、出力されるスタック トレース情報は同じになります。その理由は、現在のスレッドの現在の状態における軌跡スタックの状態が Throwabe に保存されないためです。次に、fillInStackTrace() メソッドを紹介します。この方法はまさにこの種の保存作業を行います。このメソッドのプロトタイプを見てみましょう:

java.lang.Exception: 出问题啦!
  at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
  at TestPrintStackTrace.g(TestPrintStackTrace.java:7)
  at TestPrintStackTrace.main(TestPrintStackTrace.java:16)
java.lang.Exception: 出问题啦!
  at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
  at TestPrintStackTrace.g(TestPrintStackTrace.java:7)
  at TestPrintStackTrace.main(TestPrintStackTrace.java:16)

このメソッドには戻り値があります。返されるのは、現在のスタック トレース情報を保存する Throwable オブジェクトです。 fillInStackTrace() メソッドを使用した後に出力されるスタック トレース情報の違いを見てみましょう。 コードは次のとおりです。

public Throwable fillInStackTrace()

出力は次のとおりです。

public class TestPrintStackTrace {
  public static void f() throws Exception{
    throw new Exception("出问题啦!");
  }
  public static void g() throws Exception{
    try {
      f();
    }catch(Exception e) {
      e.printStackTrace();
      //不要忘了强制类型转换
      throw (Exception)e.fillInStackTrace();
    }
     
  }
  public static void main(String[] args) {
    try {
      g();
    }catch(Exception e) {
      e.printStackTrace();
    }
  }
}

次の場合に f 関連の情報がないことがわかります。 main メソッドでスタック トレースを出力します。

以上がJava例外スタックトレースサンプルコードの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。