1. May 2020 |

Java: Erindid ja veahaldus, erindite mähkimine

Väike läbikirjutus endale ja võibolla on kellegi veel abiks.

Checked exceptions (kontrollitud erindid) – on mõtet püüda ja lahendada

Näiteks faili lugemise (readAllFiles) puhul programm ei kompileerugi enne kui pole veahaldusega tegeletud (peab panema try-catch sisse).

„Checked“ – kontrollitakse kompileerimise käigus ning sellega peab kohe tegelema (või selle erindi meetodi deklaratsioonis ära märkima, et see meetod võib erindi visata ( …method() throws Exception {… ).

Sellised erindid on Java valik. See on konkreetselt sellisteks juhtudeks, kui programmeerijal on selle peale midagi teha ka veel ehk on olukord, millega on arvestatud:

  • faili pole, siis ütled kasutajale, et „pane see sinna“, kasutada vaikimisi väärtusi, loe fail kuskilt mujalt jne.
  • võrk ei tööta, siis proovid hiljem uuesti vms

Ehk „siin võib mure olla“ ja siin on sul reaalselt midagi teha ka. Iseloomulik, et meil ei ole enne vea tekkimist võimalik seda kontrollida kood kirjutamise ajal (kas võrk tulevikus sellel hetkel töötab, kas fail tulevikus on sellel hetkel olemas).

Kontrollitud (checked) erindid on näiteks:

IOException() (input-output viga)
Exception (üldine juht)

Unchecked Exceptions – Kontrollimata erindid

Mõningatel juhtudel ei ole nii, et seal midagi enam teha oleks. Näiteks nulliga jagamise tehe ei ole defineeritud (ArithmeticException) ja seda ei ole mõtet natukese aja pärast uuesti proovida, et äkki nüüd saab või kasutajale öelda, et „ära proovi nulliga jagada“. Tõenäoliselt on tegemist programmi veaga, miks üldse sellisesse kohta jõutakse.

Liigituse aluseks:

  • Ootamatu olukord
  • Programmeerija viga (mitte see, et väljast poolt on juhtunud ettenägematu asi). Päästmine on mõttetu.

Ei ole loogiline sellistele kohtadele try-catch ümber panna või deklareerida meetodis. ArithmeticException vms püüdmine on halb praktika. Selle nulliga jagamise olukorra lahendad nii, et enne(!) kontrollid if-tingimusega, kas see asi, millega jagatakse, ei ole null. See kontrollimise võimalus on iseloomulik (erinevalt checked exceptionitest). Ei hakka püüdma.

Olukorra näiteid veel:

  • Tühjast listist küsid miinimum elementi (lahenduseks if-tingimus + throw illegalArgumentException(…))

Kontrollimata (unchecked) erindid on näiteks:

ArithmeticException()
NullPointerException()
RuntimeException() (üldine, juhtus mingisugune viga) IllegalArgumentException()
IllegalStateException (avamata failist lugemine, tühjast listist lugemine)

Sulgemine (40 min, 37-38 slaid)

.close() (faili sulgemise meetod) võib visata ka checked exceptioni. Seda ei lähe püüdma vaid lihtsalt ignoreerid või logid maha. Teed eraldi close() meetodi, mida finally blokis kasutad ja paned sinna catch (IOException ignore) {}.

Faili kinni panemata jätmine on nõme viga. Standardlahendus on finally() bloki kasutamine.

Muu

Veahaldusega tegeleb Main meetod, mitte iga alammeetod. Erind kui lisa infokanal näiteks oma erindi tegemise kaudu (eraldi klass). Main meetodis iga catch tegutseb vastavalt sellele, missuguse erindi ta kuskilt on saanud.

Erindite mähkimine (wrapping)

Näide: Püüad (IOException e) kinni ja viskad RuntimeException(e);

Checked (üsna tüütu) ja unchecked exception on võtmesõnad. Mõte on, et saaks mööda minna checked exceptioni signatuuri kirjutamisest. Püüad kinni checked exceptioni, millega ei saa tegelemata jätta ja viskad unchecked exceptioni välja. Tulemus: kui tekib viga, visatakse exception. Kuna on runtime exception, siis seda ei pea igale poole signatuuri kirja panema. Praktikas seda tehakse üsna tihti.

Mõte Javal oli tore, et kas pead kohe tegelema või paned signatuuri kirja. Tüütuvõitu.

Märkused endale:

  • Try-with-resources kasutamise peaks muutma harjumuseks, sest seda läheb väga tihti vaja. Sulgemata vood on üks kontrolltööde levinum viga. (viide)

Kasulikku lugemist: Veahaldus, erindid, TalTechi Javadoc

Leave a Reply

Your email address will not be published. Required fields are marked *