1. Obtenir une trace de pile
Le langage de programmation Java offre de nombreuses façons pour un programmeur d'obtenir des informations sur ce qui se passe dans un programme. Et pas que des mots.
Par exemple, une fois les programmes C++ compilés, ils deviennent un gros fichier rempli de code machine, et tout ce qui est disponible pour un programmeur au moment de l'exécution est l'adresse du bloc de mémoire qui contient le code machine en cours d'exécution. Pas beaucoup, disons.
Mais pour Java, même après la compilation d'un programme, les classes restent des classes, les méthodes et les variables ne disparaissent pas, et le programmeur a de nombreuses façons d'obtenir des informations sur ce qui se passe dans le programme.
Trace de la pile
Par exemple, à un moment de l'exécution d'un programme, vous pouvez connaître la classe et le nom de la méthode en cours d'exécution. Et pas seulement une méthode - vous pouvez obtenir des informations sur toute la chaîne d'appels de méthode de la méthode actuelle à la main()
méthode.
Une liste composée de la méthode actuelle, de la méthode qui l'a invoquée, de la méthode qui l'a appelée, etc. est appelée une trace de pile . Vous pouvez l'obtenir avec cette déclaration :
StackTraceElement[] methods = Thread.currentThread().getStackTrace();
Vous pouvez également l'écrire sur deux lignes :
Thread current = Thread.currentThread();
StackTraceElement[] methods = current.getStackTrace();
La currentThread()
méthode statique de la Thread
classe renvoie une référence à un Thread
objet, qui contient des informations sur le thread courant, c'est-à-dire le thread d'exécution en cours. Vous en apprendrez plus sur les threads dans les niveaux 17 et 18 de la quête Java Core .
Cet Thread
objet a une getStackTrace()
méthode, qui renvoie un tableau d' StackTraceElement
objets, chacun contenant des informations sur une méthode. Pris ensemble, tous ces éléments forment une pile trace .
Exemple:
Code |
---|
|
Sortie console |
|
Comme nous pouvons le voir dans la sortie de la console de l'exemple, la getStackTrace()
méthode a renvoyé un tableau de trois éléments :
getStackTrace()
méthode de laThread
classetest()
méthode de laMain
classemain()
méthode de laMain
classe
À partir de cette trace de pile, nous pouvons conclure que :
- La
Thread.getStackTrace()
méthode a été appelée par laMain.test()
méthode de la ligne 11 du fichier Main.java - La
Main.test()
méthode a été appelée par laMain.main()
méthode de la ligne 5 du fichier Main.java - Personne n'a appelé la
Main.main()
méthode — c'est la première méthode dans la chaîne d'appels.
Soit dit en passant, seules certaines des informations disponibles étaient affichées à l'écran. Tout le reste peut être obtenu directement à partir de l' StackTraceElement
objet
2.StackTraceElement
Comme son nom l'indique, la StackTraceElement
classe a été créée pour stocker des informations sur un élément de trace de pile , c'est-à-dire une méthode dans le fichier stack trace
.
Cette classe possède les méthodes d'instance suivantes :
Méthode | Description |
---|---|
|
Renvoie le nom de la classe |
|
Renvoie le nom de la méthode |
|
Renvoie le nom du fichier (un fichier peut contenir plusieurs classes) |
|
Renvoie le numéro de ligne dans le fichier où la méthode a été appelée |
|
Renvoie le nom du module (cela peut être null ) |
|
Renvoie la version du module (cela peut être null ) |
Ils peuvent vous aider à obtenir des informations plus complètes sur la pile d'appels actuelle :
Code | Sortie console | Note |
---|---|---|
|
|
nom de la classe nom de la méthode nom du fichier numéro de ligne nom du module version du module nom de la classe nom de la méthode nom du fichier numéro de la ligne nom du module version du module nom de la classe nom de la méthode nom du fichier numéro de la ligne nom du module version du module |
3. Pile
Vous savez déjà ce qu'est une trace de pile , mais qu'est-ce qu'une pile (classe Stack) ?
Une pile est une structure de données à laquelle vous pouvez ajouter des éléments et à partir de laquelle vous pouvez récupérer des éléments. Ce faisant, vous ne pouvez prendre que des éléments de la fin : vous prenez d'abord le dernier ajouté, puis l'avant-dernier ajouté, etc.
La pile de noms elle-même suggère ce comportement, comme la façon dont vous interagiriez avec une pile de papiers. Si vous mettez les feuilles 1, 2 et 3 en pile, vous devez les récupérer dans l'ordre inverse : d'abord la troisième feuille, puis la deuxième, et ensuite seulement la première.
Java a même une classe spéciale de collection Stack avec le même nom et le même comportement. Cette classe partage beaucoup de comportements avec ArrayList
et LinkedList
. Mais il a également des méthodes qui implémentent le comportement de la pile :
Méthodes | Description |
---|---|
|
Ajoute l' obj élément en haut de la pile |
|
Prend l'élément du haut de la pile (la profondeur de la pile diminue) |
|
Renvoie l'élément en haut de la pile (la pile ne change pas) |
|
Vérifie si la collection est vide |
|
Recherche un objet dans la collection et renvoie sonindex |
Exemple:
Code | Contenu de la pile (le haut de la pile est à droite) |
---|---|
|
|
Les piles sont assez souvent utilisées en programmation. C'est donc une collection utile.
4. Affichage d'une trace de pile lors de la gestion des exceptions
Pourquoi une liste d'appels de méthode est-elle appelée une trace de pile ? Parce que si vous considérez la liste des méthodes comme une pile de feuilles de papier avec des noms de méthode, lorsque vous appelez la méthode suivante, vous ajoutez une feuille avec le nom de cette méthode à la pile. Et la feuille de papier suivante va au-dessus de cela, et ainsi de suite.
Lorsqu'une méthode se termine, la feuille en haut de la pile est supprimée. Vous ne pouvez pas retirer une feuille du milieu de la pile sans retirer toutes les feuilles au-dessus. De même, vous ne pouvez pas terminer une méthode au milieu d'une chaîne d'appels sans terminer toutes les méthodes qu'elle a appelées.
Des exceptions
Une autre utilisation intéressante des piles est lors de la gestion des exceptions.
Lorsqu'une erreur se produit dans un programme et qu'une exception est levée , l'exception contient la trace de pile actuelle - un tableau constitué d'une liste de méthodes commençant, à partir de la méthode principale et se terminant par la méthode où l'erreur s'est produite. Il y a même la ligne où l'exception a été levée !
Cette trace de pile est stockée à l'intérieur de l'exception et peut être facilement récupérée à l'aide de la méthode suivante :StackTraceElement[] getStackTrace()
Exemple:
Code | Note |
---|---|
|
Intercepter l'exception Obtenir la trace de la pile qui existait lorsque l'erreur s'est produite. |
C'est une méthode de la Throwable
classe, donc tous ses descendants (c'est-à-dire toutes les exceptions) ont la getStackTrace()
méthode. Super pratique, hein ?
Afficher la trace de la pile de l'exception
Soit dit en passant, la Throwable
classe a une autre méthode pour travailler avec les traces de pile, une méthode qui affiche toutes les informations de trace de pile stockées dans l'exception. Il s'appelle printStackTrace()
.
Très commodément, vous pouvez l'appeler sur n'importe quelle exception.
Exemple:
Code |
---|
|
Sortie console |
|
GO TO FULL VERSION