1. Uzyskanie śladu stosu
W języku programowania Java programista ma wiele sposobów na uzyskanie informacji o tym, co aktualnie dzieje się w programie. I to nie tylko słowa.
Na przykład programy C++ po kompilacji zamieniają się w jeden duży plik kodu maszynowego, a wszystko, co jest dostępne dla programisty podczas wykonywania, to adres fragmentu pamięci, który zawiera aktualnie wykonywany kod maszynowy. Nie dużo, powiedzmy.
W Javie nawet po kompilacji klasy pozostają klasami, metody i zmienne nie znikają, a programista ma wiele sposobów na uzyskanie informacji o tym, co aktualnie dzieje się w programie.
Ślad stosu
Na przykład w dowolnym momencie działania programu można znaleźć klasę i nazwę aktualnie wykonywanej metody. I nawet nie jedną metodę, ale uzyskaj informacje o całym łańcuchu wywołań metod od bieżącej metody do main()
.
Lista składająca się z bieżącej metody, metody, która ją wywołała, metody, która ją wywołała itd., nazywana jest śladem stosu . Możesz go uzyskać za pomocą polecenia:
StackTraceElement[] methods = Thread.currentThread().getStackTrace();
Możesz też napisać to w dwóch liniach:
Thread current = Thread.currentThread();
StackTraceElement[] methods = current.getStackTrace();
Metoda currentThread()
klasy statycznej Thread
zwraca odwołanie do obiektu typu Thread
, który zawiera informacje o bieżącym wątku (o bieżącym wątku wykonania). Więcej o wątkach dowiesz się w zadaniu Java Core .
Ten obiekt Thread
ma metodę getStackTrace()
, która zwraca tablicę elementów StackTraceElement
, z których każdy zawiera informacje o jednej metodzie. Wszystkie elementy razem tworzą ślad stosu .
Przykład:
Kod |
---|
|
Wyjście na wyświetlaczu |
|
Jak widać z danych wyjściowych na ekranie, w powyższym przykładzie metoda getStackTrace()
zwróciła tablicę złożoną z trzech elementów:
- metoda
getStackTrace()
klasowaThread
- metoda
test()
klasowaMain
- metoda
main()
klasowaMain
Z tego śladu stosu możemy wywnioskować, że:
- Metoda
Thread.getStackTrace()
została wywołana przez metodęMain.test()
w linii 11 pliku Main.java - Metoda
Main.test()
została wywołana metodąMain.main()
w wierszu 5 pliku Main.java Main.main()
Nikt nie wywołał metody - jest to pierwsza metoda w łańcuchu wywołań.
Nawiasem mówiąc, na ekranie wyświetlała się tylko część wszystkich dostępnych informacji. Wszystko inne można uzyskać bezpośrednio z obiektuStackTraceElement
2.StackTraceElement
Klasa StackTraceElement
, jak sama nazwa wskazuje, jest przeznaczona do przechowywania informacji o pojedynczym elemencie śladu stosu – tj. jedna metoda z StackTrace
.
Obiekty tej klasy mają następujące metody:
metoda | Opis |
---|---|
|
Zwraca nazwę klasy |
|
Zwraca nazwę metody |
|
Zwraca nazwę pliku (jeden plik może mieć wiele klas) |
|
Zwraca numer wiersza w pliku, w którym wywołano metodę |
|
Zwraca nazwę modułu (może być null ) |
|
Zwraca wersję modułu (może być null ) |
Z ich pomocą możesz uzyskać pełniejsze informacje o bieżącym stosie wywołań:
Kod | Wyjście na wyświetlaczu | Notatka |
---|---|---|
|
|
nazwa klasy nazwa metody nazwa pliku numer linii nazwa modułu wersja modułu nazwa klasy nazwa metody nazwa pliku numer linii nazwa modułu wersja modułu nazwa klasy nazwa metody nazwa pliku nazwa linii numer linii nazwa modułu wersja modułu |
3. Stos
Co to jest Stack Trace, które już znasz, ale czym jest sam Stack ?
Stos to struktura przechowywania danych, do której można dodawać elementy iz której elementy można pobierać. Co więcej, możesz pobierać elementy tylko od końca: najpierw ostatni dodany, potem przedostatni i tak dalej.
Sama nazwa Stos jest tłumaczona z angielskiego jako „stos” i jest bardzo podobna do stosu papieru. Jeśli ułożysz arkusze 1, 2 i 3 na stosie papieru, możesz je wziąć tylko w odwrotnej kolejności: najpierw trzeci, potem drugi, a dopiero potem pierwszy.
Java ma nawet specjalną kolekcję o takim samym zachowaniu i tej samej nazwie — Stack. Ta klasa jest bardzo podobna w zachowaniu do ArrayList
i LinkedList
. Ma jednak więcej metod, które implementują zachowanie stosu:
Metody | Opis |
---|---|
|
Dodaje element obj na koniec listy (na górę stosu) |
|
Podnosi element ze szczytu stosu (wysokość stosu maleje) |
|
Zwraca element ze szczytu stosu (stos się nie zmienia) |
|
Sprawdza, czy kolekcja jest pusta |
|
Wyszukuje obiekt z kolekcji, zwraca goindex |
Przykład:
Kod | Zawartość stosu (prawy górny róg) |
---|---|
|
|
Stos jest dość często używany w programowaniu. Jest to więc przydatna kolekcja.
4. Układaj dane wyjściowe śledzenia podczas obsługi błędów
Dlaczego lista wywołań metod nosi nazwę StackTrace ? Tak, ponieważ jeśli wyobrazisz sobie listę metod jako stos arkuszy z nazwami metod, gdy wywołasz następną metodę, arkusz z nazwą metody zostanie umieszczony na tym stosie, na nim zostanie umieszczony następny i tak NA.
Po zakończeniu metody liść z wierzchu stosu jest usuwany. Nie możesz usunąć liścia ze środka stosu bez usunięcia wszystkich leżących na nim arkuszy - nie możesz zatrzymać działania metody w łańcuchu wywołań bez ukończenia wszystkich wywoływanych przez nią metod.
Wyjątki
Innym interesującym zastosowaniem stosu jest obsługa wyjątków.
Gdy w programie wystąpi błąd i zostanie zgłoszony wyjątek , zapisywany jest do niego bieżący ślad stosu : tablica składająca się z listy metod, zaczynając od metody głównej i kończąc na metodzie, w której wystąpił błąd. Jest nawet wiersz, w którym został zgłoszony wyjątek!
Ten ślad stosu błędu jest przechowywany wewnątrz wyjątku i można go łatwo odzyskać za pomocą metody:StackTraceElement[] getStackTrace()
Przykład:
Kod | Notatka |
---|---|
|
Przechwyć wyjątek Uzyskaj z niego ślad stosu w momencie wystąpienia błędu. |
Jest to metoda klasowa Throwable
, co oznacza, że wszystkie jej klasy potomne (czyli ogólnie wszystkie wyjątki) mają metodę getStackTrace()
. Bardzo wygodne, prawda?
Drukowanie śladu stosu błędów
Nawiasem mówiąc, klasa Throwable
ma jeszcze jedną metodę pracy ze śledzeniem stosu: wypisuje na konsoli wszystkie informacje dotyczące śledzenia stosu, które są przechowywane w wyjątku. Tak to się nazywa printStackTrace()
.
Możesz wywołać go na dowolnym wyjątku, co jest bardzo wygodne.
Przykład:
Kod |
---|
|
Wyjście na wyświetlaczu |
|
GO TO FULL VERSION