Lors de la programmation avec java, il y a des moments où vous voulez savoir où la méthode a été appelée. Dans ce cas, vous pouvez obtenir les informations de trace de pile et obtenir les informations sur l'appelant.
Utilisez Throwable # getStackTrace ()
pour obtenir les informations de trace de la pile.
StackTraceElement[] ste = new Throwable().getStackTrace();
for (int i = 0; i < ste.length; i++) {
System.out.println(ste[i].getClassName()); //Obtenir le nom de la classe
System.out.println(ste[i].getMethodName()); //Obtenir le nom de la méthode
System.out.println(ste[i].getFileName()); //Obtenir le nom du fichier
System.out.println(ste[i].getLineNumber()); //Obtenir le numéro de ligne (impossible d'obtenir en cas de méthode native)
System.out.println(ste[i].isNativeMethod()); //Déterminez s'il s'agit d'une méthode native.
System.out.println(ste[i]); //Formater et afficher les informations de trace de pile
}
Vous pouvez également utiliser Thread # getStackTrace ()
au lieu de Throwable # getStackTrace ()
.
StackTraceElement[] ste = Thread.currentThread().getStackTrace();
Cependant, il existe certaines différences dans les informations de trace de pile obtenues par les deux méthodes. Exécutons l'exemple de programme et vérifions-le.
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()Obtenir des informations de trace de pile à l'aide de");
StackTraceElement[] ste = new Throwable().getStackTrace();
for (int i = 0; i < ste.length; i++) {
System.out.println(ste[i]);
}
System.out.println("\nThread#getStackTrace()Obtenir des informations de trace de pile à l'aide de");
ste = Thread.currentThread().getStackTrace();
for (int i = 0; i < ste.length; i++) {
System.out.println(ste[i]);
}
}
}
Le résultat de l'exécution de l'exemple de programme est le suivant.
Throwable#getStackTrace()Obtenir des informations de trace de pile à l'aide de
sample.SampleClass1.method2(Main1.java:18)
sample.SampleClass1.method1(Main1.java:13)
sample.Main1.main(Main1.java:7)
Thread#getStackTrace()Obtenir des informations de trace de pile à l'aide de
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)
Si vous utilisez Thread # getStackTrace ()
, les informations de trace de pile seront augmentées d'une ligne.
Ce n'est pas une grande différence, vous pouvez donc utiliser l'un ou l'autre.
Il existe une limite supérieure aux informations de trace de pile qui peuvent être acquises. En d'autres termes, le "StackTraceElement []" acquis ne contient pas toujours toutes les informations de trace de pile.
Vérifions en exécutant l'exemple de programme suivant.
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);
}
}
}
Le résultat de l'exécution dépend de la JVM, mais dans mon environnement, le résultat est le suivant.
ste.length=200
ste.length=500
ste.length=1000
ste.length=1024
ste.length=1024
Vous pouvez voir que le nombre maximum d'informations de trace de pile pouvant être acquises est de «1024». En d'autres termes, il n'est pas toujours possible de retracer l'appelant jusqu'à l'origine.
Recommended Posts