Skansholm: Kapitel 11
Efter att ha studerat kod med god och mindre god felhantering insåg jag att den här frågan förtjänade mer uppmärksamhet.
Låt oss börja med att lista några rimliga önskemål om felhantering.
Det är vanligtvis en acceptabel lösning att låta ett fel upptäckas av Javas vanliga mekanismer.
Låt oss betrakta ett enkelt exempel. Din applikation hanterar ett
antal hinkar, numrerade från 0
till n-1
. Du ska implementera ett antal
operationer på hinkarna, bland annat en metod
void töm(int k)
som tömmer (nollställer) hink nummer k
. Vi antar att hinkarna
representeras med en array av int
med storlek n
.
Vi kommer att titta på några exempel på hur operationen töm()
kan
implementeras.
Den allra enklaste lösningen:
void töm(int k) { hinkar[k] = 0; }+
Vad händer om man frågar efter hink nummer -1
eller hink n+1
?
Du får en exception, ArrayIndexOutOfBoundsException
.
Det här är ofta en rimlig lösning. Det viktiga är att om programmet försöker att tömma en hink som inte finns kommer vi att uptäcka det. Det undantag som kastas är ej specifikt för applikationen men orsaken till felet är lätt att lokalisera. (Hur lokaliserar man orsaken?)
Här kollar programmet att index är inom arrayen.
void töm(int k) { if (0 <= k && k < hinkar.size) hinkar[k] = 0; }-
Vi har lagt ner mer arbete och fått en sämre lösning! Vi gömmer ju
eventuella problem. Om programmet skickar fel index till metoden töm()
får vi ingen feedback på att ett fel har inträffat.
Samma sak gäller om man skriver så här:
void töm(int k) { try hinkar[k] = 0; catch (Exception e){} }-
Den här lösningen är sämre än den föregående eftersom den också döljer alla andra fel som kan uppträda i metoden. Nu är ju vårt exempel extremt enkelt så risken att andra fel uppträder är minimal, men i en mer komplex applikation finns det en uppenbar risk att man fångar andra fel som man inte var medveten om.
Denna lösning är inte heller så bra:
boolean töm(int k) { if (0 <= k && k < hinkar.size) { hinkar[k] = 0; return true; } else return false; }-
Tanken är alltså att metoden töm()
returnerar false
om index var fel.
Vem ska testa om metoden töm()
returnerar true
eller false
? Om den som
anropar glömmer att testa upptäcks inte felet.
Om man konstruerar ett bibliotek kan följande vara rimligt:
void töm(int k) throws BucketsOutOfBoundsException { if (0 <= k && k < hinkar.size) { hinkar[k] = 0; } else throw new BucketsOutOfBoundsException(); }+
Här framgår det omedelbart att felet har att göra med en operation på hinkar, vilket kan vara till hjälp.
Lösningarna märkta med +
är bra, de märkta med -
är mindre bra.