JavaRush /Blog Java /Random-FR /Stack Trace et avec quoi il est mangé
Alukard
Niveau 37
London

Stack Trace et avec quoi il est mangé

Publié dans le groupe Random-FR
Dans cet article, vous apprendrez et comprendrez comment fonctionne le phénomène Java StackTrace, également connu sous le nom de Call Stack Tracing. Ces informations ont été structurées pour les débutants qui ont rencontré ce concept au début du niveau de syntaxe Java 9. Je pense que vous avez tous, au moins une fois, rencontré des erreurs similaires lorsque vous travailliez dans votre IDE, qu'il s'agisse de Idea , Eclipse ou autre chose.
Exception in thread "main" java.lang.ArithmeticException
	at com.example.task01.Test.division(Test.java:10)
	at com.example.task01.Test.main(Test.java:6)
Ceci, comme vous l'avez peut-être deviné, est notre traçage. Mais ne paniquez pas, nous allons maintenant détailler cet exemple pour vous. Vous devez d’abord comprendre le fait qu’il StackTracefonctionne comme Стэкson nom l’indique. À ce stade, nous allons nous attarder un peu plus en détail. Comment fonctionne la collection Stack Au huitième niveau, vous connaissez déjà les collections et savez qu'elles sont divisées en trois groupes Set- ensemble, List- liste, Map- dictionnaire (ou carte). Selon JavaRush (c). Le nôtre Stackfait partie du groupe List. Le principe de son fonctionnement peut être décrit comme LIFO , qui signifie Last In First Out. À savoir, il s’agit d’une liste similaire à une pile de livres ; pour prendre l’élément que nous avons mis en Stackpremier, nous devons d’abord extraire tous les éléments que nous avons ajoutés à notre liste par la suite. Comme indiqué dans l'image ci-dessus, contrairement, par exemple, à une liste ordinaire ArrayListoù l'on peut obtenir n'importe quel élément de la liste par index. Encore une fois en renfort. Récupérer un élément Стэкаn’est possible qu’à partir de la fin ! Alors que le premier élément qui y est ajouté se trouve au début (ou en bas, comme c'est plus pratique). Voici les méthodes dont dispose notre Stack objet push()- Ajoute un élément en haut de la pile. Objet pop()- Renvoie l'élément en haut de la pile, en le supprimant au cours du processus. Objet peek()- Renvoie l'élément en haut de la pile, mais ne le supprime pas. int search()- Recherche un élément sur la pile. S'il est trouvé, son décalage par rapport au haut de la pile est renvoyé. Sinon, -1 est renvoyé. boolean empty()- Vérifie si la pile est vide. Renvoie vrai si la pile est vide. Renvoie false si la pile contient des éléments. Alors pourquoi en avez-vous Javabesoin StackTraced’un construit sur les principes de fonctionnement Stack? Regardons ci-dessous l'exemple d'une erreur survenue lors de l'exécution d'un programme aussi simple.
public class Test {

    public static void main(String[] args) {
        System.out.println(convertStringToInt(null));
    }

    public static int convertStringToInt(String s) {
        int x = Integer.parseInt(s);
        return x;
    }
}
Nous avons une classe Testavec deux méthodes. Tout le monde est familier mainet convertStringToIntdont la logique est de convertir et de renvoyer une chaîne reçue de l'extérieur (c'est-à-dire de la méthode main) en un nombre entier de type int. Comme vous pouvez le voir, nous avons intentionnellement transmis le paramètre au lieu d'une chaîne avec un nombre null. Notre méthode n'a pas pu traiter ce paramètre correctement et a provoqué une erreur NumberFormatException. Comme vous le savez, le programme commence à élaborer son travail à partir de la méthode mainet à ce moment il en crée une nouvelle Стэкavec un nom StackTraceoù il met la valeur actuelle de son travail sous le numéro 1 , puis nous passons à nouveau à la méthode convertStringToIntet au programme entre les paramètres de notre emplacement dans celui créé précédemment StackTracesous le numéro 2 , alors cela s'appelle une méthode invisible à nos yeux parseIntsituée dans la classe Integeret ce sera déjà l'élément numéro 3 du nôtre StackTrace, dans cette méthode il y aura un autre appel interne ajouté au StackTracenuméro 4 pour vérifier l'élément pour null , ce qui entraînera une erreur. Le programme doit afficher notre erreur en indiquant toute la chaîne de nos transitions jusqu'à ce que l'erreur se produise. C'est là que celle créée précédemment avec les données de nos transitions lui vient en aide StackTrace.
Exception in thread "main" java.lang.NumberFormatException: null
	at java.base/java.lang.Integer.parseInt(Integer.java:614)
	at java.base/java.lang.Integer.parseInt(Integer.java:770)
	at com.example.task01.Test.convertStringToInt(Solution.java:10)
	at com.example.task01.Test.main(Solution.java:6)
Avant que l'erreur ne se produise, le programme a approfondi les méthodes, mais dès que l'erreur s'est produite, tout commence à se passer dans l'ordre inverse. Une ligne décrivant le problème est imprimée (n°1 dans l'exemple), puis la dernière (et en haut) valeur ajoutée à la nôtre est prise, Стэкelle était le numéro quatre et imprimée sur la console (n°2 dans l'exemple) et on voit que le problème s'est posé dans la classe Integerà la ligne 614 de code et a appelé cette ligne, ligne 770 d'une méthode parseIntde la même classe (n°3 dans l'exemple) qui, une fois ajoutée, Стэкétait le numéro trois et cette méthode de classe, Integerencore invisible pour nous, était déjà appelée par notre méthode convertStringToIntsituée à la ligne 10 de notre programme (n°4 dans l'exemple, et lors de l'ajout elle était la deuxième), et elle, à son tour, a été appelée mainà la ligne 6 (n°5 dans l'exemple, et lors de l'ajout, respectivement, du premier). Ainsi, en stockant Стекnos méthodes appelées étape par étape, nous avons pu revenir à mainl'impression parallèle des informations qui nous ont exactement conduit à l'erreur. Mais StackTracecela ne fonctionne pas seulement avec les erreurs, cela nous permet d'obtenir de nombreuses informations intéressantes sur le processus de notre candidature. Regardons un autre exemple populaire dans les commentaires du cours principal du niveau 9. Nous avons le code et je vais immédiatement y joindre une image qui visualise le processus du programme :
public class Test {
    public static void main(String[] args) {
        method1();
        method2();
    }
    public static void method1() {
        //не вызывает ничего
    }
    public static void method2() {
        method3();
        method4();
    }
    public static void method3() {
        //не вызывает ничего
    }
    public static void method4() {
        method5();
    }
    public static void method5() {
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
        for (StackTraceElement element:stackTraceElements) {
            System.out.println(element.getMethodName());
        }
    }
}
Stack Trace et avec quoi il est mangé - 2 Ici, notre programme fait parfaitement son travail et se termine. Voici ce que nous verrons dans la sortie de la console :
getStackTrace
method5
method4
method2
main

Process finished with exit code 0
Comment sommes-nous arrivés à cette conclusion et que s’est-il passé dans la cinquième méthode, à partir de la ligne 20 ? Je crains que le mieux que je puisse faire soit d'ajouter l'explication la plus populaire (abrégée) de l'utilisateur Kirill à partir des commentaires de la conférence. Passons à la ligne de création StackTraceet analysons-la élément par élément :
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
StackTraceElement[]- une indication du type du tableau (Au début, vous aviez déjà appris les tableaux comme int[], String[], ici c'est pareil). stackTraceElements- le nom du tableau peut être n'importe quoi, en tenant compte des règles générales de dénomination, cela n'affecte pas le travail. Thread.currentThread()- obtenir un lien vers le thread actuel dans lequel sont exécutées les méthodes que l'on souhaite suivre (pour l'instant ce n'est pas important, vous analyserez les threads plus en détail au niveau 16 dans la quête Java Core) getStackTrace()- on obtient toutes Стэкles méthodes appelées (C'est un getter régulier pour StackTrace) Voyons maintenant ce que le tableau créé peut nous être utile. Nous comprenons que le tableau stocke des informations sur les méthodes exécutées. (c) Et pour cela, à la 21ème ligne, on lance un cycle modifié forappelé forEach(d'ailleurs, pour ceux qui n'ont pas encore étudié ce cycle, je vous conseille de le lire) et on sort les données du tableau vers la console , à savoir des informations sur les méthodes exécutées lors des travaux utilisant la construction element.getMethodName(). Attention, comme nous le voyons, l'élément zéro du tableau s'est avéré être lui-même, getStackTrace()respectivement, puisqu'au moment de recevoir le tableau de données, c'était la dernière méthode qui a été exécutée et s'est donc retrouvée en haut Стэка, et en se souvenant de notre construction " Dernier entré, premier sorti » est immédiatement le premier à être ajouté au tableau sous l'élément zéro. Voici ce que nous pouvons obtenir d'autre StackTraceElement: String getClassName()- Renvoie le nom de la classe. String getMethodName()- Renvoie le nom de la méthode. String getFileName()- Renvoie le nom du fichier (il peut y avoir plusieurs classes dans un seul fichier). String getModuleName()- Renvoie le nom du module (peut être nul). String getModuleVersion()- Renvoie la version du module (peut être nulle). int getLineNumber()- Renvoie le numéro de ligne du fichier dans lequel la méthode a été appelée. Maintenant que vous comprenez le principe général de fonctionnement, je vous conseille d'essayer vous-même différentes méthodes StackTracedans votre Ide . Même si vous ne maîtrisez pas complètement tout, continuez à apprendre et le puzzle se déroulera de la même manière que pour moi dans ce domaine. Je vous souhaite à tous du succès ! Ps Si vous avez aimé ce matériel, veuillez le soutenir avec un like. Ce n'est pas difficile pour toi, je suis content. Merci et à bientôt au niveau 41 ;)
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION