Maison  >  Article  >  Java  >  Explication détaillée de l'exemple de code de trace de pile d'exceptions Java

Explication détaillée de l'exemple de code de trace de pile d'exceptions Java

黄舟
黄舟original
2017-03-17 10:51:331703parcourir

Cet article présente principalement l'explication détaillée de la trace de la pile d'exceptions Java (Stack Trace) et les informations associées de l'exemple de code. Les amis dans le besoin peuvent se référer à

Trace de la pile d'exceptions Java (Stack Trace) détaillée. explication

Lorsqu'une exception est détectée, un certain traitement est souvent nécessaire. Un moyen plus simple et plus direct consiste à imprimer la trace de la pile d'exceptions Stack Trace. En parlant de traces de pile, beaucoup de gens peuvent être comme moi. La première réaction est la méthode printStackTrace(). En fait, en plus de cette méthode, il existe d'autres contenus liés aux traces de pile.

1.printStackTrace()

Tout d'abord, il faut être clair que cette méthode ne provient pas de la classe Exception. À l'exception de la classe Exception elle-même, qui définit plusieurs constructeurs, toutes les méthodes sont héritées de sa classe parent. Les méthodes liées aux exceptions sont toutes héritées de la classe java.lang.Throwable. Et printStackTrace() en fait partie.

Cette méthode imprimera les informations de trace de pile de l'objet Throwable dans le flux de sortie d'erreur standard. L'apparence générale de la sortie est la suivante :

java.lang.NullPointerException
     at MyClass.mash(MyClass.java:9)
     at MyClass.crunch(MyClass.java:6)
     at MyClass.main(MyClass.java:3)

La première ligne de sortie est la sortie de la méthode toString(), et le contenu des lignes suivantes est le contenu précédemment enregistré via fillInStackTrace( ) méthode. Nous parlerons de cette méthode plus tard.

Regardons un exemple :

public class TestPrintStackTrace {
  public static void f() throws Exception{
    throw new Exception("出问题啦!");
  }
  public static void g() throws Exception{
    f();
  }
  public static void main(String[] args) {
    try {
      g();
    }catch(Exception e) {
      e.printStackTrace();
    }
  }
}

Le résultat de cet exemple est le suivant :

java.lang.Exception: 出问题啦!
  at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
  at TestPrintStackTrace.g(TestPrintStackTrace.java:6)
  at TestPrintStackTrace.main(TestPrintStackTrace.java:10)

Dans cet exemple, dans la méthode f(), renvoie Une exception se produit, la méthode f() est appelée dans la méthode g(), l'exception est interceptée dans la méthode principale et les informations de trace de pile sont imprimées. Par conséquent, la sortie montre le processus f->g->main en séquence.

Méthode 2.getStackTrace()

Cette méthode fournit un accès par programmation aux informations imprimées par la méthode printStackTrace(). Il renvoie un tableau d'éléments de trace de pile. En prenant la sortie ci-dessus comme exemple, le contenu de chaque ligne des lignes de sortie 2 à 4 correspond à un élément de trace de pile. Enregistrez ces éléments de trace de pile dans un tableau. Chaque élément correspond à un cadre de pile de la pile. Le premier élément du tableau stocke l'élément supérieur de la pile, qui se trouve au-dessus de f. L'élément inférieur de la pile enregistré par le dernier élément.

Ce qui suit est un exemple d'utilisation de getStackTrace() pour accéder à ces éléments de pile de trace et imprimer la sortie :

public class TestPrintStackTrace {
  public static void f() throws Exception{
    throw new Exception("出问题啦!");
  }
  public static void g() throws Exception{
    f();
  }
  public static void main(String[] args) {
    try {
      g();
    }catch(Exception e) {
      e.printStackTrace();
      System.out.println("------------------------------");
      for(StackTraceElement elem : e.getStackTrace()) {
        System.out.println(elem);
      }
    }
  }
}

Une telle sortie est fondamentalement la même que la sortie de printStackTrace(), comme suit :

java.lang.Exception: 出问题啦!
  at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
  at TestPrintStackTrace.g(TestPrintStackTrace.java:6)
  at TestPrintStackTrace.main(TestPrintStackTrace.java:10)
TestPrintStackTrace.f(TestPrintStackTrace.java:3)
TestPrintStackTrace.g(TestPrintStackTrace.java:6)
TestPrintStackTrace.main(TestPrintStackTrace.java:10)

3.fillInStackTrace()

Nous avons également mentionné cette méthode auparavant. Pour clarifier cette méthode, nous devons d'abord parler du problème de la relance des exceptions après les avoir détectées. Attrapez l'exception dans le bloc de code catch, imprimez la trace de la pile et jetez-la à nouveau. Dans l’appel de méthode de niveau précédent, interceptez cette exception et imprimez les informations de trace de pile. Les informations de trace des deux piles seront-elles les mêmes ? Jetons un coup d'œil au code :

public class TestPrintStackTrace {
  public static void f() throws Exception{
    throw new Exception("出问题啦!");
  }
  public static void g() throws Exception{
    try {
      f();
    }catch(Exception e) {
      e.printStackTrace();
      throw e;
    }
     
  }
  public static void main(String[] args) {
    try {
      g();
    }catch(Exception e) {
      e.printStackTrace();
    }
  }
}

L'exception interceptée dans la méthode main est levée dans la méthode g() Il va de soi que les informations des deux traces de pile imprimées devraient être différentes. La deuxième impression Les informations de ne devraient contenir aucune information sur f. Mais en fait, les informations de trace de pile imprimées deux fois sont les mêmes. Le résultat de sortie est le suivant :

java.lang.Exception: 出问题啦!
  at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
  at TestPrintStackTrace.g(TestPrintStackTrace.java:7)
  at TestPrintStackTrace.main(TestPrintStackTrace.java:16)
java.lang.Exception: 出问题啦!
  at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
  at TestPrintStackTrace.g(TestPrintStackTrace.java:7)
  at TestPrintStackTrace.main(TestPrintStackTrace.java:16)

En d'autres termes, si l'exception est interceptée et levée immédiatement, et que l'exception est à nouveau interceptée lors de l'appel de méthode supérieure, les informations de trace de pile imprimées seront les mêmes. . La raison en est que l'état de la pile de trajectoires dans l'état actuel du thread actuel n'est pas enregistré dans Throwabe. Nous introduisons maintenant la méthode fillInStackTrace(). Cette méthode fait juste ce genre de travail de préservation. Jetons un coup d'œil au prototype de cette méthode :

public Throwable fillInStackTrace()

Cette méthode a une valeur de retour. Ce qui est renvoyé est un objet Throwable qui enregistre les informations de trace de pile actuelles. Jetons un coup d'œil à la différence dans les informations de trace de pile imprimées après avoir utilisé la méthode fillInStackTrace(). Le code est le suivant :

public class TestPrintStackTrace {
  public static void f() throws Exception{
    throw new Exception("出问题啦!");
  }
  public static void g() throws Exception{
    try {
      f();
    }catch(Exception e) {
      e.printStackTrace();
      //不要忘了强制类型转换
      throw (Exception)e.fillInStackTrace();
    }
     
  }
  public static void main(String[] args) {
    try {
      g();
    }catch(Exception e) {
      e.printStackTrace();
    }
  }
}

Le résultat est le suivant :

java.lang.Exception: 出问题啦!
  at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
  at TestPrintStackTrace.g(TestPrintStackTrace.java:7)
  at TestPrintStackTrace.main(TestPrintStackTrace.java:17)
java.lang.Exception: 出问题啦!
  at TestPrintStackTrace.g(TestPrintStackTrace.java:11)
  at TestPrintStackTrace.main(TestPrintStackTrace.java:17)
Nous voyons que dans main La trace de pile imprimée dans la méthode n'a plus d'informations liées à f.


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn