Wenn Sie mit Java programmieren, möchten Sie manchmal wissen, wo die Methode aufgerufen wurde. In einem solchen Fall können Sie die Stack-Trace-Informationen und die Anruferinformationen abrufen.
Verwenden Sie Throwable # getStackTrace ()
, um die Stack-Trace-Informationen abzurufen.
StackTraceElement[] ste = new Throwable().getStackTrace();
for (int i = 0; i < ste.length; i++) {
System.out.println(ste[i].getClassName()); //Klassennamen abrufen
System.out.println(ste[i].getMethodName()); //Methodennamen abrufen
System.out.println(ste[i].getFileName()); //Dateinamen abrufen
System.out.println(ste[i].getLineNumber()); //Zeilennummer abrufen (kann bei nativer Methode nicht abgerufen werden)
System.out.println(ste[i].isNativeMethod()); //Stellen Sie fest, ob es sich um eine native Methode handelt.
System.out.println(ste[i]); //Formatieren und Anzeigen von Stack-Trace-Informationen
}
Sie können auch "Thread # getStackTrace ()" anstelle von "Throwable # getStackTrace ()" verwenden.
StackTraceElement[] ste = Thread.currentThread().getStackTrace();
Es gibt jedoch einige Unterschiede in den Stapelverfolgungsinformationen, die durch die beiden Methoden erhalten werden. Lassen Sie uns das Beispielprogramm ausführen und überprüfen.
Main1
package sample;
public class Main1 {
public static void main(String[] args) {
SampleClass1 sc = new SampleClass1();
sc.method1();
}
}
class SampleClass1 {
public void method1() {
method2();
}
public void method2() {
System.out.println("Throwable#getStackTrace()Holen Sie sich Stack-Trace-Informationen mit");
StackTraceElement[] ste = new Throwable().getStackTrace();
for (int i = 0; i < ste.length; i++) {
System.out.println(ste[i]);
}
System.out.println("\nThread#getStackTrace()Holen Sie sich Stack-Trace-Informationen mit");
ste = Thread.currentThread().getStackTrace();
for (int i = 0; i < ste.length; i++) {
System.out.println(ste[i]);
}
}
}
Das Ergebnis der Ausführung des Beispielprogramms ist wie folgt.
Throwable#getStackTrace()Holen Sie sich Stack-Trace-Informationen mit
sample.SampleClass1.method2(Main1.java:18)
sample.SampleClass1.method1(Main1.java:13)
sample.Main1.main(Main1.java:7)
Thread#getStackTrace()Holen Sie sich Stack-Trace-Informationen mit
java.lang.Thread.getStackTrace(Thread.java:1556)
sample.SampleClass1.method2(Main1.java:24)
sample.SampleClass1.method1(Main1.java:13)
sample.Main1.main(Main1.java:7)
Wenn Sie "Thread # getStackTrace ()" verwenden, werden die Stack-Trace-Informationen um eine Zeile erhöht. Es ist kein großer Unterschied, also können Sie beide verwenden.
Es gibt eine Obergrenze für die Stapelverfolgungsinformationen, die erfasst werden können. Mit anderen Worten, das erfasste "StackTraceElement []" enthält nicht immer alle Stack-Trace-Informationen.
Lassen Sie uns dies überprüfen, indem Sie das folgende Beispielprogramm ausführen.
Main2
package sample;
public class Main2 {
public static void main(String[] args) {
SampleClass2 sc = new SampleClass2();
sc.printStackTrace(200);
sc.printStackTrace(500);
sc.printStackTrace(1000);
sc.printStackTrace(2000);
sc.printStackTrace(3000);
}
}
class SampleClass2 {
public void printStackTrace(int stackCount) {
if (stackCount > 2) {
printStackTrace(stackCount - 1);
} else {
StackTraceElement[] ste = new Throwable().getStackTrace();
System.out.println("ste.length=" + ste.length);
}
}
}
Das Ausführungsergebnis hängt von der JVM ab, aber in meiner Umgebung ist die Ausgabe wie folgt.
ste.length=200
ste.length=500
ste.length=1000
ste.length=1024
ste.length=1024
Sie können sehen, dass die maximale Anzahl von Stapelverfolgungsinformationen, die erfasst werden können, "1024" beträgt. Mit anderen Worten, es ist nicht immer möglich, den Anrufer bis zum Ursprung zurückzuverfolgen.
Recommended Posts