1. Een stacktracering verkrijgen
De programmeertaal Java biedt een programmeur vele manieren om informatie te krijgen over wat er in een programma gebeurt. En niet alleen woorden.
Nadat bijvoorbeeld C++-programma's zijn gecompileerd, worden ze één groot bestand vol machinecode, en het enige dat tijdens runtime beschikbaar is voor een programmeur is het adres van het geheugenblok dat de machinecode bevat die momenteel wordt uitgevoerd. Niet veel zullen we maar zeggen.
Maar voor Java blijven klassen, zelfs nadat een programma is gecompileerd, klassen, verdwijnen methoden en variabelen niet en heeft de programmeur veel manieren om informatie te krijgen over wat er in het programma gebeurt.
Stapel traceren
Op een bepaald moment tijdens de uitvoering van een programma kunt u bijvoorbeeld de klasse en naam achterhalen van de methode die momenteel wordt uitgevoerd. En niet slechts één methode - u kunt informatie krijgen over de hele keten van methodeaanroepen van de huidige methode terug naar de main()
methode.
Een lijst die bestaat uit de huidige methode en de methode die deze heeft aangeroepen, en de methode die deze heeft aangeroepen, enz. wordt een stacktracering genoemd . Je kunt het krijgen met deze verklaring:
StackTraceElement[] methods = Thread.currentThread().getStackTrace();
Je kunt het ook als twee regels schrijven:
Thread current = Thread.currentThread();
StackTraceElement[] methods = current.getStackTrace();
De statische currentThread()
methode van de Thread
klasse retourneert een verwijzing naar een Thread
object, dat informatie bevat over de huidige thread, dwz de huidige uitvoeringsthread. Je leert meer over threads in niveau 17 en 18 van de Java Core- zoektocht.
Dit Thread
object heeft een getStackTrace()
methode, die een reeks StackTraceElement
objecten retourneert, die elk informatie over een methode bevatten. Samen vormen al deze elementen een stacktracering .
Voorbeeld:
Code |
---|
|
Console-uitvoer |
|
Zoals we kunnen zien in de console-uitvoer van het voorbeeld, getStackTrace()
retourneerde de methode een array van drie elementen:
getStackTrace()
werkwijze van deThread
klastest()
werkwijze van deMain
klasmain()
werkwijze van deMain
klas
Uit deze stacktrace kunnen we concluderen dat:
- De
Thread.getStackTrace()
methode werd aangeroepen door deMain.test()
methode op regel 11 van het bestand Main.java - De
Main.test()
methode werd aangeroepen door deMain.main()
methode op regel 5 van het bestand Main.java - Niemand heeft de
Main.main()
methode aangeroepen — dit is de eerste methode in de keten van aanroepen.
Overigens werd slechts een deel van de beschikbare informatie op het scherm weergegeven. StackTraceElement
Al het andere kan rechtstreeks van het object worden verkregen
2.StackTraceElement
Zoals de naam al doet vermoeden, StackTraceElement
is de klasse gemaakt om informatie op te slaan over een stacktrace- element, dwz één methode in het stack trace
.
Deze klasse heeft de volgende instantiemethoden:
Methode | Beschrijving |
---|---|
|
Retourneert de naam van de klasse |
|
Retourneert de naam van de methode |
|
Retourneert de naam van het bestand (één bestand kan meerdere klassen bevatten) |
|
Retourneert het regelnummer in het bestand waar de methode werd aangeroepen |
|
Retourneert de naam van de module (dit kan zijn null ) |
|
Retourneert de versie van de module (dit kan null ) |
Ze kunnen u helpen meer volledige informatie te krijgen over de huidige call-stack:
Code | Console-uitvoer | Opmerking |
---|---|---|
|
|
klassenaam methodenaam bestandsnaam regelnummer modulenaam moduleversie klassenaam methodenaam bestandsnaam regelnummer modulenaam moduleversie klassenaam methodenaam bestandsnaam regelnummer modulenaam moduleversie |
3. Stapelen
U weet al wat een stacktrace is, maar wat is een stack (Stack-klasse)?
Een stapel is een gegevensstructuur waaraan u elementen kunt toevoegen en waaruit u elementen kunt ophalen. Daarbij kun je alleen elementen van het einde nemen: je neemt eerst de laatst toegevoegde, dan de op een na laatste toegevoegde, etc.
De naamstapel zelf suggereert dit gedrag, zoals hoe je zou omgaan met een stapel papieren. Als je bladen 1, 2 en 3 op een stapel legt, moet je ze in omgekeerde volgorde terughalen: eerst het derde blad, dan het tweede en dan pas het eerste.
Java heeft zelfs een speciale Stack-verzamelklasse met dezelfde naam en hetzelfde gedrag. Deze klas deelt veel gedragingen met ArrayList
en LinkedList
. Maar het heeft ook methoden die stapelgedrag implementeren:
methoden | Beschrijving |
---|---|
|
Voegt het obj element toe aan de bovenkant van de stapel |
|
Neemt het element van de bovenkant van de stapel (de stapeldiepte neemt af) |
|
Retourneert het item bovenaan de stapel (de stapel verandert niet) |
|
Controleert of de verzameling leeg is |
|
Zoekt naar een object in de verzameling en geeft het terugindex |
Voorbeeld:
Code | Stapelinhoud (de bovenkant van de stapel bevindt zich aan de rechterkant) |
---|---|
|
|
Stapels worden vrij vaak gebruikt bij het programmeren. Dit is dus een nuttige verzameling.
4. Een stacktracering weergeven tijdens het afhandelen van uitzonderingen
Waarom wordt een lijst met methodeaanroepen een stacktrace genoemd ? Want als je de lijst met methoden ziet als een stapel vellen papier met methodenamen, dan voeg je bij het aanroepen van de volgende methode een blad met de naam van die methode toe aan de stapel. En het volgende vel papier komt daar bovenop, enzovoort.
Wanneer een methode eindigt, wordt het vel bovenaan de stapel verwijderd. U kunt geen vel uit het midden van de stapel halen zonder alle vellen erboven te verwijderen. Evenzo kunt u een methode niet midden in een aanroepketen beëindigen zonder alle aangeroepen methoden te beëindigen.
Uitzonderingen
Een ander interessant gebruik van stapels is tijdens het afhandelen van uitzonderingen.
Wanneer er een fout optreedt in een programma en er een uitzondering wordt gegenereerd , bevat de uitzondering de huidige stacktracering — een array die bestaat uit een lijst met methoden die begint bij de hoofdmethode en eindigt met de methode waar de fout is opgetreden. Er is zelfs de lijn waar de uitzondering werd gegooid!
Deze stacktracering wordt binnen de uitzondering opgeslagen en kan er eenvoudig uit worden opgehaald met behulp van de volgende methode:StackTraceElement[] getStackTrace()
Voorbeeld:
Code | Opmerking |
---|---|
|
Vang de uitzondering Haal de stacktracering op die bestond toen de fout optrad. |
Dit is een methode van de Throwable
klasse, dus al zijn afstammelingen (dwz alle uitzonderingen) hebben de getStackTrace()
methode. Superhandig toch?
Geef de stacktracering van de uitzondering weer
Overigens Throwable
heeft de klasse een andere methode om met stacktraceringen te werken, een methode die alle stacktrace-informatie weergeeft die in de uitzondering is opgeslagen. Het wordt genoemd printStackTrace()
.
Heel handig, je kunt het op elke uitzondering noemen.
Voorbeeld:
Code |
---|
|
Console-uitvoer |
|
GO TO FULL VERSION