2 votes

Pourquoi j'obtiens des traces de pile différentes avec java.lang.Throwable#getStackTrace et java.lang.Thread#getStackTrace ?

Voici le code :

package stacktrace.test;

public class A {
    public static void main(String[] args) {
        B.f();
    }
}

interface B {
    static void f() {
        C.f();
    }
}

interface C {
    static void f() {
        StackTraceElement[] stackTrace1 = (new Exception()).getStackTrace();
        StackTraceElement[] stackTrace2 = Thread.currentThread().getStackTrace();
        StackTraceElement x1 = stackTrace1[1];
        StackTraceElement x2 = stackTrace2[1];
        System.out.println(x1.getClassName());
        System.out.println(x2.getClassName());
    }
}

Et la production :

stacktrace.test.B
stacktrace.test.C

Je vérifie le Thread.currentThread().getStackTrace() il appelle (new Exception()).getStackTrace(); . Dans ce cas, pourquoi est-ce que j'obtiens des résultats différents ?

Merci d'avance !

1voto

dasblinkenlight Points 264350

Pour comprendre ce qui se passe, commencez par imprimer l'intégralité de la trace de la pile, élément par élément. Voici ce que vous allez obtenir ( démo ) :

-- stackTrace1
C.f(Main.java:23)
B.f(Main.java:17)
A.main(Main.java:11)

-- stackTrace2
java.lang.Thread.getStackTrace(Thread.java:1556)
C.f(Main.java:24)
B.f(Main.java:17)
A.main(Main.java:11)

Notez que la seule différence réside dans l'élément initial des deux traces de pile : la seconde contient une image supplémentaire au sommet.

Il semble que la méthode qui remplit la pile d'un Throwable exclut le cadre avec le constructeur de l'élément Throwable ou de sa sous-classe, ainsi que d'autres méthodes appelées lors de sa construction.

C'est logique, car lorsque vous voyez la trace de pile d'une exception, vous voulez voir la méthode de lancement en haut, et ne pas tenir compte du fait que la création de l'exception a nécessité l'appel à son constructeur.

Les fils getStackTrace() en revanche, ne se retire pas de la pile. C'est ce que vous voyez en haut de la pile lorsque vous l'imprimez.

1voto

apangin Points 4693

Comme vous l'avez remarqué vous-même, Thread.currentThread().getStackTrace() appels (new Exception()).getStackTrace(); Cela signifie que la trace de pile du premier sera plus longue d'une image exactement.

Si une méthode en appelle une autre, leurs traces de pile ne peuvent pas être identiques, par définition.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X