1. Soorten uitzonderingen
Alle uitzonderingen zijn onderverdeeld in 4 typen, die eigenlijk klassen zijn die elkaar overerven.
Throwable
klas
De basisklasse voor alle uitzonderingen is de Throwable
klasse. De Throwable
klasse bevat de code die de huidige call-stack (stacktracering van de huidige methode) naar een array schrijft. We zullen later leren wat een stacktracering is.
De throw- operator kan alleen een object accepteren dat is afgeleid van de Throwable
klasse. En hoewel je in theorie code kunt schrijven als throw new Throwable();
, doet meestal niemand dit. Het belangrijkste doel van de Throwable
klasse is om één enkele bovenliggende klasse te hebben voor alle uitzonderingen.
Error
klas
De volgende uitzonderingsklasse is de Error
klasse, die de klasse rechtstreeks overerft Throwable
. De Java-machine maakt objecten van de Error
klasse (en zijn afstammelingen) wanneer er ernstige problemen zijn opgetreden . Bijvoorbeeld een hardwarestoring, onvoldoende geheugen, enz.
Gewoonlijk kun je als programmeur niets doen in een situatie waarin een dergelijke fout (het soort waarvoor een Error
moet worden gegenereerd) in het programma is opgetreden: deze fouten zijn te ernstig. Het enige wat u kunt doen is de gebruiker op de hoogte stellen dat het programma crasht en/of alle bekende informatie over de fout naar het programmalogboek schrijven.
Exception
klas
De klassen Exception
en RuntimeException
zijn voor veelvoorkomende fouten die optreden bij de werking van veel methoden. Het doel van elke gegooide uitzondering is om te worden opgevangen door een catch
blok dat weet hoe het op de juiste manier moet worden afgehandeld.
Wanneer een methode om de een of andere reden zijn werk niet kan voltooien, moet deze de aanroepende methode onmiddellijk op de hoogte stellen door een uitzondering van het juiste type te genereren.
Met andere woorden, als een variabele gelijk is aan null
, zal de methode een NullPointerException
. Als de onjuiste argumenten aan de methode zijn doorgegeven, wordt een InvalidArgumentException
. Als de methode per ongeluk door nul deelt, wordt een ArithmeticException
.
RuntimeException
klas
RuntimeExceptions
zijn een subset van Exceptions
. We zouden zelfs kunnen zeggen dat RuntimeException
dit een lichtgewicht versie is van gewone uitzonderingen ( Exception
) — aan dergelijke uitzonderingen worden minder eisen en beperkingen gesteld
Je leert het verschil tussen Exception
en RuntimeException
later.
2. Throws
: aangevinkte uitzonderingen
Alle Java-uitzonderingen vallen in 2 categorieën: aangevinkt en niet aangevinkt .
Alle uitzonderingen die de uitzonderingen erven RuntimeException
of Error
worden beschouwd als ongecontroleerde uitzonderingen . Alle andere zijn gecontroleerde uitzonderingen .
Twintig jaar nadat gecontroleerde uitzonderingen werden geïntroduceerd, beschouwt bijna elke Java-programmeur dit als een bug. In populaire moderne frameworks is 95% van alle uitzonderingen niet aangevinkt. De C#-taal, die Java bijna exact kopieerde, voegde geen gecontroleerde uitzonderingen toe .
Wat is het belangrijkste verschil tussen aangevinkte en ongecontroleerde uitzonderingen?
Aan aangevinkte uitzonderingen worden aanvullende eisen gesteld . Grofweg zijn dit deze:
Vereiste 1
Als een methode een aangevinkte uitzondering genereert , moet deze het type uitzondering aangeven in de handtekening . Op die manier weet elke methode die het aanroept dat deze "betekenisvolle uitzondering" erin kan voorkomen.
Geef aangevinkte uitzonderingen aan na de methodeparameters achter het throws
trefwoord (gebruik het trefwoord niet throw
per ongeluk). Het ziet er ongeveer zo uit:
type method (parameters) throws exception
Voorbeeld:
aangevinkte uitzondering | ongecontroleerde uitzondering |
---|---|
|
|
In het voorbeeld aan de rechterkant genereert onze code een ongecontroleerde uitzondering — er is geen aanvullende actie vereist. In het voorbeeld aan de linkerkant genereert de methode een aangevinkte uitzondering, dus het throws
sleutelwoord wordt toegevoegd aan de handtekening van de methode, samen met het type uitzondering.
Als een methode meerdere aangevinkte uitzonderingen verwacht , moeten ze allemaal worden opgegeven na het throws
trefwoord, gescheiden door komma's. De volgorde is niet belangrijk. Voorbeeld:
public void calculate(int n) throws Exception, IOException
{
if (n == 0)
throw new Exception("n is null!");
if (n == 1)
throw new IOException("n is 1");
}
Vereiste 2
Als u een methode aanroept die uitzonderingen in zijn handtekening heeft gecontroleerd , kunt u niet negeren dat deze uitzonderingen genereert.
U moet al dergelijke uitzonderingen opvangen door catch
voor elke uitzondering blokken toe te voegen, of door ze toe te voegen aan een throws
clausule voor uw methode.
Het is alsof we zeggen: " Deze uitzonderingen zijn zo belangrijk dat we ze moeten opvangen. En als we niet weten hoe we ze moeten aanpakken, dan moet iedereen die onze methode aanroept, ervan op de hoogte worden gebracht dat dergelijke uitzonderingen erin kunnen voorkomen.
Voorbeeld:
Stel je voor dat we een methode schrijven om een door mensen bevolkte wereld te creëren. Het aanvankelijke aantal mensen wordt als argument doorgegeven. We moeten dus uitzonderingen toevoegen als er te weinig mensen zijn.
Aarde creëren | Opmerking |
---|---|
|
De methode genereert mogelijk twee gecontroleerde uitzonderingen:
|
Deze methodeaanroep kan op 3 manieren worden afgehandeld:
1. Vang geen uitzonderingen op
Dit wordt meestal gedaan wanneer de methode niet weet hoe ze de situatie goed moet aanpakken.
Code | Opmerking |
---|---|
|
De aanroepende methode vangt de uitzonderingen niet op en moet anderen erover informeren: het voegt ze toe aan zijn eigen throws clausule |
2. Vang enkele van de uitzonderingen op
Wij pakken de fouten aan die we aankunnen. Maar degenen die we niet begrijpen, gooien we over naar de aanroepmethode. Om dit te doen, moeten we hun naam toevoegen aan de throws-clausule:
Code | Opmerking |
---|---|
|
De beller vangt slechts één aangevinkte uitzondering op — LonelyWorldException . De andere uitzondering moet aan de handtekening worden toegevoegd en wordt aangegeven na het throws trefwoord |
3. Vang alle uitzonderingen op
Als de methode geen uitzonderingen op de aanroepende methode genereert, is de aanroepende methode er altijd zeker van dat alles goed werkte. En het zal geen actie kunnen ondernemen om uitzonderlijke situaties op te lossen.
Code | Opmerking |
---|---|
|
Alle uitzonderingen worden in deze methode opgevangen. De beller weet zeker dat alles goed is gegaan. |
3. Meerdere uitzonderingen opvangen
Programmeurs hebben er echt een hekel aan om code te dupliceren. Ze kwamen zelfs met een bijbehorend ontwikkelprincipe: DRY : Don't Repeat Yourself. Maar bij het afhandelen van uitzonderingen komt het regelmatig voor dat een try
blok wordt gevolgd door meerdere catch
blokken met dezelfde code.
Of er kunnen 3 catch
blokken zijn met dezelfde code en nog eens 2 catch
blokken met een andere identieke code. Dit is een standaardsituatie wanneer uw project verantwoord omgaat met uitzonderingen.
Vanaf versie 7 is in de Java-taal de mogelijkheid toegevoegd om meerdere soorten uitzonderingen in één catch
blok op te geven. Het ziet er ongeveer zo uit:
try
{
// Code where an exception might occur
}
catch (ExceptionType1 | ExceptionType2 | ExceptionType3 name)
{
// Exception handling code
}
Je kunt zoveel catch
blokken hebben als je wilt. Een enkel blok kan echter catch
geen uitzonderingen specificeren die elkaar overerven. Met andere woorden, u kunt catch ( Exception
| RuntimeException
e) niet schrijven, omdat de RuntimeException
klasse overerft Exception
.
GO TO FULL VERSION