JavaRush /Java-Blog /Random-DE /Stack Trace und womit es gegessen wird
Alukard
Level 37
London

Stack Trace und womit es gegessen wird

Veröffentlicht in der Gruppe Random-DE
In diesem Artikel erfahren und verstehen Sie, wie das Java-Phänomen StackTrace, auch bekannt als Call Stack Tracing, funktioniert. Diese Informationen wurden für Anfänger strukturiert, die dieses Konzept zu Beginn der Java-Syntaxstufe 9 kennengelernt haben. Ich denke, Sie alle sind bei der Arbeit in Ihrer IDE mindestens einmal auf ähnliche Fehler gestoßen, unabhängig davon, ob es sich um Idea , Eclipse oder etwas anderes handelte.
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)
Wie Sie vielleicht schon erraten haben, handelt es sich hier um unsere Spurensuche. Aber geraten Sie nicht in Panik, jetzt werden wir dieses Beispiel für Sie aufschlüsseln. Zuerst müssen Sie verstehen, dass es so StackTracefunktioniert, wie Стэкder Name vermuten lässt. An dieser Stelle werden wir etwas näher darauf eingehen. So funktioniert die Stack-Sammlung Auf der achten Ebene haben Sie Sammlungen bereits kennengelernt und wissen, dass sie in drei Gruppen unterteilt sind Set– Set, List– Liste, Map– Wörterbuch (oder Karte). Laut JavaRush (c). Unseres Stackist Teil der Gruppe List. Das Funktionsprinzip kann als LIFO beschrieben werden , was für „Last In First Out“ steht. Dies ist nämlich eine Liste, die einem Stapel Bücher ähnelt; um das Element zu übernehmen, das wir Stackzuerst eingefügt haben, müssen wir zunächst alle Elemente extrahieren, die wir danach zu unserer Liste hinzugefügt haben. Wie im Bild oben angedeutet, anders als beispielsweise bei einer regulären Liste, ArrayListbei der wir jedes Element aus der Liste anhand des Index abrufen können. Noch einmal zur Verstärkung. Das Erhalten eines Elements Стэкаist nur vom Ende her möglich! Während das erste hinzugefügte Element am Anfang steht (oder am unteren Ende, wie es praktischer ist). Dies sind die Methoden, über die unser Stack Objekt verfügt push(): Fügt ein Element oben im Stapel hinzu. Objekt pop()– Gibt das Element oben im Stapel zurück und entfernt es dabei. Objekt peek()– Gibt das Element oben im Stapel zurück, entfernt es jedoch nicht. int search()– Sucht nach einem Element auf dem Stapel. Wenn es gefunden wird, wird sein Versatz vom oberen Rand des Stapels zurückgegeben. Andernfalls wird -1 zurückgegeben. boolean empty()– Prüft, ob der Stapel leer ist. Gibt true zurück, wenn der Stapel leer ist. Gibt false zurück, wenn der Stapel Elemente enthält. Warum Javabrauchen Sie also StackTraceein Gerät, das auf den Funktionsprinzipien basiert Stack? Schauen wir uns unten das Beispiel eines Fehlers an, der während der Ausführung eines so einfachen Programms aufgetreten ist.
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;
    }
}
Wir haben eine Klasse Testmit zwei Methoden. Jeder kennt maindie convertStringToIntLogik, die darin besteht, einen von außen (nämlich von der Methode main) empfangenen String in eine Ganzzahl vom Typ umzuwandeln und zurückzugeben int. Wie Sie sehen, haben wir den Parameter absichtlich anstelle einer Zeichenfolge mit einer Zahl übergeben null. Unsere Methode konnte diesen Parameter nicht korrekt verarbeiten und verursachte einen Fehler NumberFormatException. Wie Sie wissen, beginnt das Programm, seine Arbeit aus der Methode herauszuarbeiten, mainund erstellt in diesem Moment eine neue Стэкmit einem Namen StackTrace, in der es den aktuellen Wert seiner Arbeit unter Nummer 1convertStringToInt einfügt. Anschließend gehen wir wieder zur Methode und zum Programm über Gibt die Parameter unseres Standorts in die zuvor StackTraceunter Nummer 2parseInt erstellte ein, dann wird eine für unsere Augen unsichtbare Methode in der Klasse aufgerufen Integerund dies wird bereits Element Nummer 3 von uns sein StackTrace. In dieser Methode wird ein weiterer interner Aufruf hinzugefügt zu StackTraceNummer 4 , um das Element auf Null zu überprüfen , was zu einem Fehler führt. Das Programm muss unseren Fehler anzeigen und die gesamte Kette unserer Übergänge bis zum Auftreten des Fehlers angeben. Hier kommt ihr das zuvor mit den Daten unserer Übergänge erstellte zu Hilfe 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)
Bevor der Fehler auftrat, ging das Programm tief in die Methoden ein, aber sobald der Fehler auftrat, begann alles in umgekehrter Reihenfolge. Eine Zeile, die das Problem beschreibt, wird gedruckt (Nr. 1 im Beispiel), dann wird der letzte (und oberste) zu unserem Wert hinzugefügte Wert genommen, Стэкes war Nummer vier und auf der Konsole gedruckt (Nr. 2 im Beispiel) und Wir sehen, dass das Problem in der Klasse Integerin Codezeile 614 auftrat und diese Zeile, Zeile 770, einer Methode parseIntderselben Klasse (Nr. 3 im Beispiel) auftrat, die, wenn sie hinzugefügt wurde, СтэкNummer drei und diese Klassenmethode war. Integerfür uns immer noch nicht sichtbar, wurde bereits von unserer Methode aufgerufen convertStringToInt, die sich in Zeile 10 unseres Programms befand (Nr. 4 im Beispiel, und beim Hinzufügen war sie die zweite), und sie wurde wiederum mainin Zeile 6 (Nr. 5) aufgerufen im Beispiel bzw. beim Hinzufügen des ersten). Durch die Стекschrittweise Speicherung unserer aufgerufenen Methoden konnten wir also zum mainparallelen Drucken der Informationen zurückkehren, die uns genau zum Fehler führten. Dabei geht es aber StackTracenicht nur um die Arbeit mit Fehlern, sondern es ermöglicht uns auch, viele interessante Informationen über den Ablauf unserer Bewerbung zu erhalten. Schauen wir uns ein weiteres beliebtes Beispiel in den Kommentaren zur Hauptvorlesung der Stufe 9 an. Wir haben den Code und ich hänge gleich ein Bild an, das den Ablauf des Programms visualisiert:
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 und womit es gegessen wird - 2 Hier erledigt unser Programm seine Arbeit einwandfrei und endet. Das sehen wir in der Konsolenausgabe:
getStackTrace
method5
method4
method2
main

Process finished with exit code 0
Wie sind wir zu dieser Schlussfolgerung gekommen und was geschah in der fünften Methode ab Zeile 20? Ich fürchte, das Beste, was ich tun kann, ist, die beliebteste Erklärung (gekürzt) von Benutzer Kirill aus den Kommentaren zum Vortrag hinzuzufügen. Wenden wir uns der Schöpfungslinie zu StackTraceund analysieren sie Element für Element:
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
StackTraceElement[]- ein Hinweis auf den Typ des Arrays (Auf frühen Ebenen haben Sie bereits etwas über Arrays wie int[], String[] gelernt, hier ist es dasselbe). stackTraceElements- Der Name des Arrays kann unter Berücksichtigung der allgemeinen Namensregeln beliebig sein, dies hat keinen Einfluss auf die Arbeit. Thread.currentThread()- Erhalten eines Links zum aktuellen Thread, in dem die Methoden ausgeführt werden, die wir verfolgen möchten (im Moment ist dies nicht wichtig, Sie werden Threads auf Stufe 16 in der Java Core-Quest detaillierter analysieren) getStackTrace()- wir erhalten alle Стэкaufgerufenen Methoden (Dies ist ein regulärer Getter für StackTrace) Nun wollen wir sehen, was das erstellte Array für uns nützlich sein könnte. Wir verstehen, dass das Array Informationen über ausgeführte Methoden speichert. (c) Und dazu starten wir in der 21. Zeile einen modifizierten Zyklus fornamens forEach(übrigens, für diejenigen, die diesen Zyklus noch nicht studiert haben, rate ich Ihnen, darüber zu lesen) und geben Daten vom Array an die Konsole aus , nämlich Informationen darüber, welche Methoden während der Arbeiten am Bau angewendet wurden element.getMethodName(). Achtung, wie wir sehen, stellte sich heraus, dass das Nullelement des Arrays es selbst war, getStackTrace()da es zum Zeitpunkt des Empfangs des Datenarrays die letzte Methode war, die ausgeführt wurde und dadurch ganz oben landete Стэка, und wir erinnern uns an unsere Konstruktion. „Last in, first out “ ist sofort das erste, das dem Array unter dem Nullelement hinzugefügt wird. Folgendes können wir sonst noch erhalten StackTraceElement: String getClassName()– Gibt den Namen der Klasse zurück. String getMethodName()– Gibt den Namen der Methode zurück. String getFileName()– Gibt den Dateinamen zurück (eine Datei kann viele Klassen enthalten). String getModuleName()– Gibt den Modulnamen zurück (kann null sein). String getModuleVersion()– Gibt die Modulversion zurück (kann null sein). int getLineNumber()– Gibt die Zeilennummer in der Datei zurück, in der die Methode aufgerufen wurde. Nachdem Sie nun das allgemeine Funktionsprinzip verstanden haben, rate ich Ihnen, StackTracein Ihrem Ide selbst verschiedene Methoden auszuprobieren . Auch wenn Sie noch nicht alles vollständig beherrschen, lernen Sie weiter und das Rätsel wird genauso ausfallen wie bei mir in dieser Angelegenheit. Ich wünsche euch allen viel Erfolg! Ps. Wenn Ihnen dieses Material gefallen hat, unterstützen Sie es bitte mit einem „Gefällt mir“. Es ist nicht schwer für dich, ich freue mich. Danke und wir sehen uns auf Level 41 ;)
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION