Programmeren in Java/Exceptions
Excepties in Java maken het mogelijk om net als in sommige andere talen zoals C++ een speciale afhandeling te doen van bepaalde scenario's. Door excepties te gebruiken is het vaak mogelijk om ingewikkelde if-structuren te vermijden en onderscheid te maken tussen de normale afhandeling van een methode en de uitzonderlijke gevallen.
Een voorbeeld van een exceptie is als je een getal converteert van een stringrepresentatie naar een int. Het kan voorkomen dat de string helemaal geen getal bevat zoals '455', maar een woord bevat zoals 'banaan'. Bij de conversie zal dan een exceptie opgegooid worden.
Try en catch
bewerkenAls je "risicocode" uitvoert die een fout kan veroorzaken (of in javajargon: een exceptie kan gooien), dien je dit op te vangen in een try-catch-(finally-)blok:
int getal = Integer.parseInt(tekst);
en dient opgevangen te worden aan de hand van een try-en-catch-constructie.
Java-code: korte code
try {
int getal = Integer.parseInt(tekst);
System.out.println("Het is gelukt om " + tekst + " om te zetten: " + getal);
} catch (NumberFormatException fout) {
System.out.println("Het is niet gelukt om " + tekst + " om te zetten naar een getal.");
}
In een uitgewerkt programma werkt dat zo:
Java-code: tryAndCatch.java
public class tryAndCatch {
public static void main(String[] args){
zetOm("34");
zetOm("3A");
zetOm("22");
}
public static void zetOm(String tekst) {
try {
int getal = Integer.parseInt(tekst);
System.out.println("Het is gelukt om " + tekst + " om te zetten: " + getal);
} catch (NumberFormatException fout) {
System.out.println("Het is niet gelukt om " + tekst + " om te zetten naar een getal.");
}
}
}
Het is gelukt om 34 om te zetten: 34 Het is niet gelukt om 3A om te zetten naar een getal. Het is gelukt om 22 om te zetten: 22
Als je probeert code te schrijven die een bepaalde verplicht af te vangen exceptie niet opvangt, dan zal de javacompiler je daarover waarschuwen. Hierboven kan je code zien die een NumberFormatException kan gooien.
finally
bewerkenMet finally kan je ervoor zorgen dat er, zelfs al treedt er een fout op, toch iets gedaan wordt. In het volgende geval krijg je altijd een vermenigvuldiging, zelfs al was er een deling door nul.
Java-code: het gooien van een fout
public class Main {
public static void main(String[] args) {
int lijst[] = {3, 2, 1, 0, -1};
int eenGetal = 12;
for (int i=0;i<lijst.length;i++)
{
try {
System.out.println(eenGetal + " / " + lijst[i] +
" = " + eenGetal/lijst[i]);
}
catch (ArithmeticException e) {
System.out.println("Deling door nul (" + e.getMessage() + ")");
}
finally {
System.out.println(eenGetal + " x " + lijst[i] +
" = " + eenGetal * lijst[i]);
}
}
}
}
12 / 3 = 4 12 x 3 = 36 12 / 2 = 6 12 x 2 = 24 12 / 1 = 12 12 x 1 = 12 Deling door nul (/ by zero) 12 x 0 = 0 12 / -1 = -12 12 x -1 = -12
Throws-clausule
bewerkenAls je een exceptie wenst te gooien om de gebruiker van je functie te informeren over een exceptie die opgetreden is en die enkel afgehandeld kan worden door de aanroeper, kan je het sleutelwoord throws gebruiken. Met deze aanroep kan je dus zelf bestaande excepties opgooien. Ook kan je zelf exceptieklasses maken door deze af te leiden van java.lang.Exception.
De afhandeling van de fout in bovenstaand voorbeeld kan dus ook afgewenteld worden op het hoofdprogramma:
Java-code: het gooien van een fout
public static void zetOm(String tekst) throws NumberFormatException {
int getal = Integer.parseInt(tekst);
System.out.println("Het is gelukt " + tekst + " om te zetten: " + getal);
}
Een uitgewerkt voorbeeld ziet er als volgt uit:
Java-code: gooien.java
public class gooien {
public static void main(String[] args){
int i = 0;
String[] rij = {"12","2C","22"};
for (i = 0; i < rij.length; i++){
try {
zetOm(rij[i]);
} catch (NumberFormatException foutmelding) {
System.out.println("Het is niet gelukt om " + rij[i] + " om te zetten naar een getal.");
}
}
}
public static void zetOm(String tekst) throws NumberFormatException {
int getal = Integer.parseInt(tekst);
System.out.println("Het is gelukt " + tekst + " om te zetten: " + getal);
}
}
Het is gelukt 12 om te zetten: 12 Het is niet gelukt om 2C om te zetten naar een getal. Het is gelukt 22 om te zetten: 22
Eigen exceptions
bewerkenHet is ook mogelijk om je eigen exception te definiëren in java:
Java-code: MijnException.java
public class MijnException extends Exception {
public MijnException(String error) {
super(error);
}
public void eenMethode(){
System.out.println("MijnException.eenMethode() aangeroepen");
}
}
Dit definieert de exception MijnException. Omdat hij de class Exception direct overerft, is het een zogeheten checked exception. (Het volgende hoofdstuk bevat meer info hierover.) Om deze exception te gooien in de code gebruikt men het woordje throw. Voorbeeld:
Java-code: ThrowMijnException.java
public class ThrowMijnException {
public static void main(String[] arg) {
try
{
throw new MijnException("Mijn error");
System.out.println("Dit komt nooit op het scherm");
}
catch(MijnException error)
{
System.out.println("De error is: "+error.getMessage()); // De methode getMessage() is gedefinieerd in java.lang.Throwable
error.eenMethode();
}
}
}
Soorten
bewerkenoorsprong
bewerken- uit Exception-class
- RuntimeException
- IndexOutOfBoundsException gevraagd element bestaat niet in de rij
- NullPointerException pointer verwijst naar nergens
- IOException uit java.io-package
- EOFException onverwacht einde van het bestand
- FileNotFoundException bestand niet gevonden
Inhoudelijk
bewerken- checked exceptions zijn exceptions waarvan de compiler verwacht dat je ze vermeldt in de methodsignatuur of opvangt in een try-en-catch-blok. Je code zal niet kunnen compileren indien je ze nergens opvangt.
Je moet deze excepties dus altijd opvangen, anders geraakt de code niet gecompileerd. Ze zijn afgeleid (inherited) van de klasse java.lang.Throwable
- unchecked exceptions hoef je niet te vermelden in de methodsignatuur en hoef je geen try-en-catch-blok voor coderen. Wanneer zich tijdens de uitvoering van een programma een onafgevangen unchecked exception voordoet, zal de JRE deze opvangen. Let op, je programma wordt afgebroken zonder dat dit invloed heeft naar het besturingssysteem toe. Meestal is het dus wel aangeraden om ook deze exceptions op te vangen of te vermelden.
Deze excepties kunnen, maar moeten dus niet opgevangen worden. Deze worden afgeleid van java.lang.Error en java.lang.RuntimeException.