1. Verem nyomkövetése

A Java programozási nyelv számos lehetőséget kínál a programozó számára, hogy információt szerezzen arról, hogy mi történik a programban. És nem csak szavak.
Például a C++ programok lefordítása után egyetlen nagy fájl lesz, amely tele van gépi kóddal, és futás közben csak az éppen végrehajtott gépi kódot tartalmazó memóriablokk címe áll a programozó rendelkezésére. Mondjuk nem sok.
A Java esetében azonban az osztályok a program lefordítása után is osztályok maradnak, a metódusok és a változók nem tűnnek el, és a programozónak számos módja van, hogy információt szerezzen a programban zajló eseményekről.
Veremnyom
Például egy program végrehajtásának pontján megtudhatja az éppen végrehajtott metódus osztályát és nevét. És nem csak egy metódus – információkat kaphat a metódushívások teljes láncáról az aktuális metódustól a metódusig main().
Az aktuális metódusból és az azt meghívó metódusból és az azt meghívó metódusból stb. álló listát veremkövetésnek nevezzük . Ezzel a nyilatkozattal érheti el:
StackTraceElement[] methods = Thread.currentThread().getStackTrace();
Két sorban is írhatod:
Thread current = Thread.currentThread();
StackTraceElement[] methods = current.getStackTrace();
Az osztály statikus currentThread()metódusa Threadegy hivatkozást ad vissza egy objektumra Thread, amely információt tartalmaz az aktuális szálról, azaz az aktuális végrehajtási szálról. A Java Core küldetés 17. és 18. szintjén lévő szálakról többet megtudhat .
Ennek Threadaz objektumnak van egy getStackTrace()metódusa, amely objektumok tömbjét adja vissza StackTraceElement, amelyek mindegyike egy metódusra vonatkozó információkat tartalmaz. Mindezek az elemek együttesen egy veremnyomot alkotnak .
Példa:
| Kód |
|---|
|
| Konzol kimenet |
|
Amint a példa konzol kimenetén láthatjuk, a getStackTrace()metódus három elemből álló tömböt adott vissza:
getStackTrace()Threadosztály módszeretest()Mainosztály módszeremain()Mainosztály módszere
Ebből a veremnyomból a következőkre következtethetünk:
- A metódust a Main.java fájl 11. sorában található metódus
Thread.getStackTrace()hívta megMain.test() - A metódust a Main.java fájl 5. sorában található metódus
Main.test()hívta megMain.main() - Senki nem hívta a
Main.main()metódust – ez az első módszer a hívások láncolatában.
A képernyőn egyébként csak néhány elérhető információ jelent meg. StackTraceElementMinden mást közvetlenül az objektumtól kaphatunk
2.StackTraceElement
Ahogy a neve is sugallja, az StackTraceElementosztályt úgy hozták létre, hogy információkat tároljon egy verem nyomelemről , azaz az egyik metódusról a stack trace.
Ennek az osztálynak a következő példánymódszerei vannak:
| Módszer | Leírás |
|---|---|
|
Az osztály nevét adja vissza |
|
A metódus nevét adja vissza |
|
A fájl nevét adja vissza (egy fájl több osztályt is tartalmazhat) |
|
A fájl sorszámát adja vissza, ahol a metódus meghívásra került |
|
A modul nevét adja vissza (ez lehet null) |
|
A modul verzióját adja vissza (ez lehet null) |
Segítségükkel teljesebb információkat kaphat az aktuális hívásveremről:
| Kód | Konzol kimenet | jegyzet |
|---|---|---|
|
|
osztálynév metódusnév fájlnév sorszám modulnév modul verzió osztálynév metódusnév fájlnév sorszám modulnév modul verzió osztálynév metódusnév fájlnév sorszám modulnév modul verzió |
3. Verem
Már tudod, mi az a veremnyom , de mi az a verem (Stack class)?
A verem egy olyan adatstruktúra, amelyhez elemeket adhat hozzá, és amelyből elemeket kérhet le. Ennek során csak a végéről vehetünk át elemeket: először az utoljára hozzáadott, majd a második utolsót stb.
Maga a köteg név is ezt a viselkedést sugallja, például azt, hogy hogyan kommunikálna egy köteg papírral. Ha az 1., 2. és 3. lapot egy kötegbe rakja, akkor fordított sorrendben kell elővennie őket: először a harmadik lapot, majd a másodikat, és csak azután az elsőt.
A Java-nak még egy speciális Stack gyűjteményosztálya is van, ugyanazzal a névvel és viselkedéssel. Ez az osztály sok magatartást tanúsít ArrayListés LinkedList. De vannak olyan módszerei is, amelyek a verem viselkedését valósítják meg:
| Mód | Leírás |
|---|---|
|
Hozzáadja az objelemet a verem tetejéhez |
|
Elveszi az elemet a verem tetejéről (a verem mélysége csökken) |
|
A köteg tetején lévő elemet adja vissza (a köteg nem változik) |
|
Ellenőrzi, hogy a gyűjtemény üres-e |
|
Megkeres egy objektumot a gyűjteményben, és visszaadja aztindex |
Példa:
| Kód | A halom tartalma (a köteg teteje a jobb oldalon található) |
|---|---|
|
|
A veremeket meglehetősen gyakran használják a programozásban. Szóval ez egy hasznos gyűjtemény.
4. Veremkövetés megjelenítése kivételkezelés során
Miért nevezik a metódushívások listáját veremkövetésnek ? Mert ha a módszerek listáját metódusnevekkel ellátott papírlapok kötegének tekinti, akkor a következő metódus meghívásakor hozzáad egy lapot a módszer nevével a köteghez. És a következő papírlap erre megy, és így tovább.
Amikor egy módszer véget ér, a köteg tetején lévő lapot eltávolítjuk. Nem távolíthat el egy lapot a köteg közepéről anélkül, hogy eltávolítaná az összes felette lévő lapot. Hasonlóképpen, nem zárhat le egy metódust a hívások láncolatának közepén anélkül, hogy az összes meghívott metódust ne befejezné.
Kivételek
A veremek másik érdekes felhasználási módja a kivételkezelés.
Ha hiba történik egy programban, és kivételt adnak ki , a kivétel tartalmazza az aktuális verem nyomkövetést – egy tömböt, amely metódusok listájából áll, a fő metódustól kezdve a hiba előfordulásának módszerével végződve. Még az a sor is ott van, ahol a kivételt dobták!
Ez a veremnyom a kivételen belül van tárolva, és könnyen visszakereshető belőle a következő módszerrel:StackTraceElement[] getStackTrace()
Példa:
| Kód | jegyzet |
|---|---|
|
A kivétel elkapása Szerezze le a verem nyomkövetését, amely a hiba bekövetkeztekor létezett. |
Ez az osztály metódusa Throwable, tehát minden leszármazottja (vagyis minden kivétel) rendelkezik ezzel a getStackTrace()módszerrel. Szuper kényelmes, mi?
A kivétel veremnyomának megjelenítése
Egyébként az Throwableosztálynak van egy másik metódusa a verem nyomkövetésekkel való munkához, egy olyan metódus, amely megjeleníti a kivételen belül tárolt összes veremnyomkövetési információt. Úgy hívják printStackTrace().
Meglehetősen kényelmesen, bármilyen kivétellel hívhatja.
Példa:
| Kód |
|---|
|
| Konzol kimenet |
|
GO TO FULL VERSION