7.5 Der Stack Trace
 
Die virtuelle Maschine merkt sich auf einem Stapel, welche Methode welche andere Methode aufgerufen hat. Diese Geschichte nennt sich Stack Trace. Wenn also die statische main()-Funktion die Funktion println() aufruft, und die wiederum print(), so sieht der Stapel zum Zeitpunkt von print() so aus:
print
println
main
7.5.1 Stack Trace aus Throwable
 
Ein Stack Trace ist im Fehlerfall nützlich, denn so lässt sich ablesen, wie die Aufruf-Geschichte war. Abrufbar ist ein Stack Trace daher bei den Fehler-Objekten, deren Basisklasse Throwable ist.
class java.lang. Throwable
implements Serializable
|
|
void printStackTrace()
Schreibt das Throwable und anschließend den Stack-Inhalt in den Standardausgabestrom. |
|
void printStackTrace( PrintStream s )
Schreibt das Throwable und anschließend den Stack-Inhalt in den angegebenen PrintStream. |
|
void printStackTrace( PrintWriter s )
Schreibt das Throwable und anschließend den Stack-Inhalt in den angegebenen PrintWriter. |
Doch auch ohne Ausnahme bekommen wir einen Aufruf-Stack. Der zum Zeitpunkt eines Methodenaufrufs aufgebaute Stack lässt sich mit einer Throwable-Funktion erfragen. Damit lassen sich Schlüssel über den Programmablauf rekonstruieren.
StackTraceElement[] trace = new Throwable().getStackTrace();
Wir erkennen, dass jede Methode durch ein StackTraceElement-Objekt repräsentiert ist. Dies erlaubt den Zugriff auf den Dateinamen, in dem die Methode definiert wurde, die Programmzeile, den Methodennamen und die Information darüber, ob die Methode nativ ist oder nicht.
Sehen wir uns das Beispiel eines Programms an, welches mehrere Methoden aufruft. Im letzten Schritt wollen wir den Stack ausgeben. Ein StackTraceElement definiert eine toString()-Methode, die alle Informationen abgibt.
Listing 7.14
GetStackTrace.java
public class GetStackTrace
{
public static void showTrace()
{
for ( StackTraceElement trace : new Throwable().getStackTrace() )
System.out.println( trace );
}
public static void m( int n )
{
if ( n == 0 )
showTrace();
else
m( n – 1 );
}
public static void main( String[] args )
{
m( 2 );
}
}
Das Programm gibt aus:
GetStackTrace.showTrace(GetStackTrace.java:5)
GetStackTrace.m(GetStackTrace.java:12)
GetStackTrace.m(GetStackTrace.java:14)
GetStackTrace.m(GetStackTrace.java:14)
GetStackTrace.main(GetStackTrace.java:19)
7.5.2 Stack Trace aus Thread
 
Seit Java 5 bietet die Thread-Klasse mit zwei Methoden eine Alternative, auch ohne neue Exception-Objekte an die StackTraceElemente zu kommen:
class java.lang. Thread
implements Runnable
|
|
static Map<Thread,StackTraceElement[]> getAllStackTraces()
Die statische Methode liefert von allen Threads in einem Assoziativspeicher ein Feld von StackTraceElement-Objekten. |
|
StackTraceElement[] getStackTrace()
Liefert den Stack-Trace für den Thread. |
Beispiel Finde heraus, in welcher Methode wir gerade stehen:
StackTraceElement e = Thread.currentThread().getStackTrace()[2];
System.out.println( e.getMethodName() );
Intern könnte sich durchaus die Position verschieben!
|
|