スタックトレース
日本語 | 積み上げ軌跡 |
英語 | stack trace |
ふりがな | すたっくとれーす |
フリガナ | スタックトレース |
特定のメソッドが呼ばれるまでに経てきたメソッドの一覧。
あるメソッドは、通常他のメソッドから呼ばれ、そのメソッドも他のメソッドから呼ばれ、そのメソッドも他のメソッドから呼ばれ……と続き、最終的にはmain()メソッドから呼ばれている。
この「あるメソッドが呼ばれるまでの、メソッドの呼び重ね」は全て保存されている。
このメソッドの情報は、それぞれのメソッドに格納されたローカル変数と共に「スタック」形式でメモリ(スタック領域)に格納される。ローカル変数は最後に呼ばれたメソッドの変数から消されるためである。
この「メソッドの呼び重ね」の一覧を「スタックトレース」と呼ぶ。
スタックトレースは、例外が投げられたときに、投げられた箇所を特定するために出力することが多い。
スタックトレースは、ThrowableクラスのprintStackTrace()メソッドで標準エラー出力に出力できる。また、getStackTrace()メソッドで詳しいスタックトレースが格納されたStackTraceElementクラスの配列も取得できる。
ThreadクラスのdumpStack()メソッドであれば、例外に関係なくいつでもスタックトレースを出力できる。
また、開発環境の多くはブレークポイントで実行を一時停止した際に、スタックトレースを表示する機能がある。
Eclipseであれば、「デバッグ」ビューでスタックトレースを見ることができる。
あるメソッドは、通常他のメソッドから呼ばれ、そのメソッドも他のメソッドから呼ばれ、そのメソッドも他のメソッドから呼ばれ……と続き、最終的にはmain()メソッドから呼ばれている。
この「あるメソッドが呼ばれるまでの、メソッドの呼び重ね」は全て保存されている。
このメソッドの情報は、それぞれのメソッドに格納されたローカル変数と共に「スタック」形式でメモリ(スタック領域)に格納される。ローカル変数は最後に呼ばれたメソッドの変数から消されるためである。
この「メソッドの呼び重ね」の一覧を「スタックトレース」と呼ぶ。
スタックトレースは、例外が投げられたときに、投げられた箇所を特定するために出力することが多い。
スタックトレースは、ThrowableクラスのprintStackTrace()メソッドで標準エラー出力に出力できる。また、getStackTrace()メソッドで詳しいスタックトレースが格納されたStackTraceElementクラスの配列も取得できる。
ThreadクラスのdumpStack()メソッドであれば、例外に関係なくいつでもスタックトレースを出力できる。
また、開発環境の多くはブレークポイントで実行を一時停止した際に、スタックトレースを表示する機能がある。
Eclipseであれば、「デバッグ」ビューでスタックトレースを見ることができる。
// Sample.java
public class Sample
{
public static void main( String[] args )
{
try
{
int i = 100;
// この変数は「先」に作られたため、消されるのは
// 「後」になります。
main2();
}
catch( RuntimeException e )
{
// ThrowableクラスのprintStackTrace()メソッドで、
// 投げられた時点でのスタックトレースを出力
// できます。
e.printStackTrace();
// java.lang.RuntimeException
// at Sample.main3(Sample.java:70)
// at Sample.main2(Sample.java:43)
// at Sample.main(Sample.java:11)
// また、getStackTrace()メソッドでさらに詳しい
// スタックトレースを取得できます。
StackTraceElement[] stackTraceElements = e.getStackTrace();
for( int iF1 = 0; iF1 < stackTraceElements.length; ++iF1 )
{
System.out.print( stackTraceElements[iF1].getFileName() );
System.out.print( ": " );
System.out.print( stackTraceElements[iF1].getClassName() );
System.out.print( "." );
System.out.print( stackTraceElements[iF1].getMethodName() );
System.out.print( "(" );
System.out.print( stackTraceElements[iF1].getLineNumber() );
System.out.println( ")" );
}
// Sample.java: Sample.main3(77)
// Sample.java: Sample.main2(50)
// Sample.java: Sample.main(11)
}
}
/**
* 2番目に呼ばれるメソッド。
*/
private static void main2()
{
int i = 100;
main3();
}
/**
* 3番目に呼ばれるメソッド。
*/
private static void main3()
{
int i = 100;
// この変数は「後」に作られたため、消されるのは
// 「先」になります。
// ここまで、main()、main2()、main3()メソッドを
// 呼んできたということがそのまま残っています。
// また、それぞれのローカル変数iも残っています。
// このiの情報がスタック形式で格納されているので、
// 「スタックトレース」と呼ばれます。
// そのスタックトレースを出力します。
Thread.dumpStack();
// java.lang.Exception: Stack trace
// at java.lang.Thread.dumpStack(Thread.java:1071)
// at Sample.main3(Sample.java:37)
// at Sample.main2(Sample.java:18)
// at Sample.main(Sample.java:9)
// 例外も投げてみます。
throw new RuntimeException();
}
}
public class Sample
{
public static void main( String[] args )
{
try
{
int i = 100;
// この変数は「先」に作られたため、消されるのは
// 「後」になります。
main2();
}
catch( RuntimeException e )
{
// ThrowableクラスのprintStackTrace()メソッドで、
// 投げられた時点でのスタックトレースを出力
// できます。
e.printStackTrace();
// java.lang.RuntimeException
// at Sample.main3(Sample.java:70)
// at Sample.main2(Sample.java:43)
// at Sample.main(Sample.java:11)
// また、getStackTrace()メソッドでさらに詳しい
// スタックトレースを取得できます。
StackTraceElement[] stackTraceElements = e.getStackTrace();
for( int iF1 = 0; iF1 < stackTraceElements.length; ++iF1 )
{
System.out.print( stackTraceElements[iF1].getFileName() );
System.out.print( ": " );
System.out.print( stackTraceElements[iF1].getClassName() );
System.out.print( "." );
System.out.print( stackTraceElements[iF1].getMethodName() );
System.out.print( "(" );
System.out.print( stackTraceElements[iF1].getLineNumber() );
System.out.println( ")" );
}
// Sample.java: Sample.main3(77)
// Sample.java: Sample.main2(50)
// Sample.java: Sample.main(11)
}
}
/**
* 2番目に呼ばれるメソッド。
*/
private static void main2()
{
int i = 100;
main3();
}
/**
* 3番目に呼ばれるメソッド。
*/
private static void main3()
{
int i = 100;
// この変数は「後」に作られたため、消されるのは
// 「先」になります。
// ここまで、main()、main2()、main3()メソッドを
// 呼んできたということがそのまま残っています。
// また、それぞれのローカル変数iも残っています。
// このiの情報がスタック形式で格納されているので、
// 「スタックトレース」と呼ばれます。
// そのスタックトレースを出力します。
Thread.dumpStack();
// java.lang.Exception: Stack trace
// at java.lang.Thread.dumpStack(Thread.java:1071)
// at Sample.main3(Sample.java:37)
// at Sample.main2(Sample.java:18)
// at Sample.main(Sample.java:9)
// 例外も投げてみます。
throw new RuntimeException();
}
}
// Sample.java public class Sample { public static void main( String[] args ) { try { int i = 100; // この変数は「先」に作られたため、消されるのは // 「後」になります。 main2(); } catch( RuntimeException e ) { // ThrowableクラスのprintStackTrace()メソッドで、 // 投げられた時点でのスタックトレースを出力 // できます。 e.printStackTrace(); // java.lang.RuntimeException // at Sample.main3(Sample.java:70) // at Sample.main2(Sample.java:43) // at Sample.main(Sample.java:11) // また、getStackTrace()メソッドでさらに詳しい // スタックトレースを取得できます。 StackTraceElement[] stackTraceElements = e.getStackTrace(); for( int iF1 = 0; iF1 < stackTraceElements.length; ++iF1 ) { System.out.print( stackTraceElements[iF1].getFileName() ); System.out.print( ": " ); System.out.print( stackTraceElements[iF1].getClassName() ); System.out.print( "." ); System.out.print( stackTraceElements[iF1].getMethodName() ); System.out.print( "(" ); System.out.print( stackTraceElements[iF1].getLineNumber() ); System.out.println( ")" ); } // Sample.java: Sample.main3(77) // Sample.java: Sample.main2(50) // Sample.java: Sample.main(11) } } /** * 2番目に呼ばれるメソッド。 */ private static void main2() { int i = 100; main3(); } /** * 3番目に呼ばれるメソッド。 */ private static void main3() { int i = 100; // この変数は「後」に作られたため、消されるのは // 「先」になります。 // ここまで、main()、main2()、main3()メソッドを // 呼んできたということがそのまま残っています。 // また、それぞれのローカル変数iも残っています。 // このiの情報がスタック形式で格納されているので、 // 「スタックトレース」と呼ばれます。 // そのスタックトレースを出力します。 Thread.dumpStack(); // java.lang.Exception: Stack trace // at java.lang.Thread.dumpStack(Thread.java:1071) // at Sample.main3(Sample.java:37) // at Sample.main2(Sample.java:18) // at Sample.main(Sample.java:9) // 例外も投げてみます。 throw new RuntimeException(); } }