1. Obținerea unei urme a stivei
Limbajul de programare Java oferă un programator mai multe modalități de a obține informații despre ceea ce se întâmplă într-un program. Și nu doar cuvinte.
De exemplu, după ce programele C++ sunt compilate, acestea devin un fișier mare plin de cod de mașină și tot ceea ce este disponibil pentru un programator în timpul rulării este adresa blocului de memorie care conține codul de mașină în curs de executare. Nu multe, să zicem.
Dar pentru Java, chiar și după ce un program este compilat, clasele rămân clase, metodele și variabilele nu dispar, iar programatorul are multe modalități de a obține informații despre ceea ce se întâmplă în program.
Urmă stivă
De exemplu, în momentul execuției unui program, puteți afla clasa și numele metodei în curs de executare. Și nu doar o metodă - puteți obține informații despre întregul lanț de apeluri de metodă de la metoda curentă înapoi la metodă main()
.
O listă care constă din metoda curentă și metoda care a invocat-o și metoda care a numit-o pe aceea etc. se numește urmă de stivă . O poți obține cu această declarație:
StackTraceElement[] methods = Thread.currentThread().getStackTrace();
De asemenea, îl puteți scrie pe două rânduri:
Thread current = Thread.currentThread();
StackTraceElement[] methods = current.getStackTrace();
Metoda statică currentThread()
a Thread
clasei returnează o referință la un Thread
obiect, care conține informații despre firul curent, adică firul curent de execuție. Veți afla mai multe despre firele de discuție la nivelurile 17 și 18 ale misiunii Java Core .
Acest Thread
obiect are o getStackTrace()
metodă, care returnează o matrice de StackTraceElement
obiecte, fiecare dintre ele conținând informații despre o metodă. Luate împreună, toate aceste elemente formează o urmă de stivă .
Exemplu:
Cod |
---|
|
Ieșire de consolă |
|
După cum putem vedea în rezultatul consolei din exemplu, getStackTrace()
metoda a returnat o matrice de trei elemente:
getStackTrace()
metodaThread
claseitest()
metodaMain
claseimain()
metodaMain
clasei
Din această urmărire a stivei, putem concluziona că:
- Metoda
Thread.getStackTrace()
a fost apelată prinMain.test()
metoda de pe linia 11 a fișierului Main.java - Metoda
Main.test()
a fost apelată prinMain.main()
metoda de pe linia 5 a fișierului Main.java - Nimeni nu a numit
Main.main()
metoda — aceasta este prima metodă din lanțul de apeluri.
Apropo, doar o parte din informațiile disponibile au fost afișate pe ecran. Orice altceva poate fi obținut direct de la StackTraceElement
obiect
2.StackTraceElement
După cum sugerează și numele, StackTraceElement
clasa a fost creată pentru a stoca informații despre un element de urmărire a stivei , adică o metodă din stack trace
.
Această clasă are următoarele metode de instanță:
Metodă | Descriere |
---|---|
|
Returnează numele clasei |
|
Returnează numele metodei |
|
Returnează numele fișierului (un fișier poate conține mai multe clase) |
|
Returnează numărul liniei din fișierul în care a fost apelată metoda |
|
Returnează numele modulului (acesta poate fi null ) |
|
Returnează versiunea modulului (aceasta poate fi null ) |
Acestea vă pot ajuta să obțineți informații mai complete despre stiva de apeluri curentă:
Cod | Ieșire de consolă | Notă |
---|---|---|
|
|
Nume de clasă Nume de metodă Nume de fișier Număr de linie Nume de modul Versiune de modul Nume de clasă Nume de metodă Nume de fișier Numă de linie Nume de modul Modul de versiune Nume de clasă Nume de metodă Nume de fișier Nume de linie Nume de linie Nume de modul Modul de versiune |
3. Stiva
Știți deja ce este o urmă de stivă , dar ce este o stivă (clasa stivă)?
O stivă este o structură de date la care puteți adăuga elemente și din care puteți prelua elemente. Procedând astfel, puteți lua doar elemente de la sfârșit: mai întâi îl luați pe ultimul adăugat, apoi pe ultimul adăugat, etc.
Teancul de nume în sine sugerează acest comportament, cum ar fi modul în care ați interacționa cu un teanc de hârtie. Dacă puneți foile 1, 2 și 3 într-un teanc, trebuie să le recuperați în ordine inversă: mai întâi a treia foaie, apoi a doua și abia apoi prima.
Java are chiar și o clasă specială de colecție Stack cu același nume și același comportament. Această clasă împărtășește o mulțime de comportamente cu ArrayList
și LinkedList
. Dar are și metode care implementează comportamentul stivei:
Metode | Descriere |
---|---|
|
Adaugă obj elementul în partea de sus a stivei |
|
Preia elementul din partea de sus a stivei (adâncimea stivei scade) |
|
Returnează articolul din partea de sus a stivei (stiva nu se schimbă) |
|
Verifică dacă colecția este goală |
|
Caută un obiect din colecție și returnează acestaindex |
Exemplu:
Cod | Conținutul stivei (partea de sus a stivei este în dreapta) |
---|---|
|
|
Stivele sunt folosite destul de des în programare. Deci aceasta este o colecție utilă.
4. Afișarea unei urme de stivă în timpul gestionării excepțiilor
De ce o listă de apeluri de metodă este numită urmărire stivă ? Pentru că dacă te gândești la lista de metode ca la un teanc de foi de hârtie cu nume de metode, atunci când apelezi următoarea metodă, adaugi o foaie cu numele acelei metode în teanc. Și următoarea foaie de hârtie merge deasupra acesteia și așa mai departe.
Când o metodă se termină, foaia din partea de sus a stivei este îndepărtată. Nu puteți scoate o foaie din mijlocul stivei fără a îndepărta toate foile de deasupra acesteia. În mod similar, nu puteți termina o metodă în mijlocul unui lanț de apeluri fără a termina toate metodele pe care le-a apelat.
Excepții
O altă utilizare interesantă pentru stive este în timpul gestionării excepțiilor.
Atunci când apare o eroare într-un program și se aruncă o excepție , excepția conține următorul stivă curent - o matrice constând dintr-o listă de metode care pornesc, de la metoda principală și se termină cu metoda în care a apărut eroarea. Există chiar și linia în care a fost aruncată excepția!
Această urmărire a stivei este stocată în interiorul excepției și poate fi extrasă cu ușurință din ea folosind următoarea metodă:StackTraceElement[] getStackTrace()
Exemplu:
Cod | Notă |
---|---|
|
Prindeți excepția Obțineți urmărirea stivei care exista atunci când a apărut eroarea. |
Aceasta este o metodă a Throwable
clasei, deci toți descendenții ei (adică toate excepțiile) au getStackTrace()
metoda. Super convenabil, nu?
Afișează urmărirea stivei excepției
Apropo, Throwable
clasa are o altă metodă de lucru cu urmele stivei, o metodă care afișează toate informațiile despre urmele stivei stocate în interiorul excepției. Se numește printStackTrace()
.
Destul de convenabil, îl puteți apela cu orice excepție.
Exemplu:
Cod |
---|
|
Ieșire de consolă |
|
GO TO FULL VERSION