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 Thread
egy 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 Thread
az 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()
Thread
osztály módszeretest()
Main
osztály módszeremain()
Main
osztá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. StackTraceElement
Minden mást közvetlenül az objektumtól kaphatunk
2.StackTraceElement
Ahogy a neve is sugallja, az StackTraceElement
osztá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 obj elemet 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 Throwable
osztá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