Sisällys. 14. Poikkeukset. Johdanto. Johdanto

Samankaltaiset tiedostot
14. Poikkeukset 14.1

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

14. Poikkeukset 14.1

Poikkeustenkäsittely

Olio-ohjelmointi Virhetilanteiden käsittely

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op. Poikkeukset ja tietovirrat: Virhetilanteiden ja syötevirtojen käsittely

Mitä poikkeuskäsittely tarkoittaa?

Sisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä

8. Näppäimistöltä lukeminen 8.1

815338A Ohjelmointikielten periaatteet

12. Näppäimistöltä lukeminen 12.1

8. Näppäimistöltä lukeminen 8.1

Sisältö. Johdanto. Tiedostojen lukeminen. Tiedostojen kirjoittaminen. 6.2

Sisältö Johdanto. Tiedostojen lukeminen. Tiedostojen kirjoittaminen. 26.2

Sisältö. Johdanto. Tiedostojen lukeminen. Tiedostojen kirjoittaminen. 6.2

Sisältö. 22. Taulukot. Yleistä. Yleistä

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

Sisältö. 2. Taulukot. Yleistä. Yleistä

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa();

Tehtävä 1. Tehtävä 2. Arvosteluperusteet Koherentti selitys Koherentti esimerkki

7. Oliot ja viitteet 7.1

Olio-ohjelmointi Javalla

Metodien tekeminen Javalla

Java-API, rajapinnat, poikkeukset, UML,...

9. Periytyminen Javassa 9.1

Mikä yhteyssuhde on?

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. X Poikkeusten käsittelystä

Luokka Murtoluku uudelleen. Kirjoitetaan luokka Murtoluku uudelleen niin, että murtolukujen sieventäminen on mahdollista.

16. Javan omat luokat 16.1

15. Ohjelmoinnin tekniikkaa 15.1

Listarakenne (ArrayList-luokka)

Ohjelmointi 2 / 2008 Välikoe / Pöytätestaa seuraava ohjelma.

Rajapinta (interface)

1. Omat operaatiot 1.1

7. Näytölle tulostaminen 7.1

17. Javan omat luokat 17.1

9. Periytyminen Javassa 9.1

Harjoitus 4 (viikko 47)

15. Ohjelmoinnin tekniikkaa 15.1

Ohjelmoinnin jatkokurssi, kurssikoe

Sisällys. 7. Oliot ja viitteet. Olion luominen. Olio Java-kielessä

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen

20. Javan omat luokat 20.1

Sisällys. 20. Javan omat luokat. Java API. Pakkaukset. java\lang

Kompositio. Mikä komposition on? Kompositio vs. yhteyssuhde Kompositio Javalla Konstruktorit set-ja get-metodit tostring-metodi Pääohjelma

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä

A) on käytännöllinen ohjelmointitekniikka. = laajennetaan aikaisemmin tehtyjä luokkia (uudelleenkäytettävyys)

Metodit Arvotyyppi. Metodit Arvotyyppi. Metodit Parametrit. Metodit Parametrit. Metodit Kuormittaminen. Metodit Kuormittaminen. Javan perusteet

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2

Java kahdessa tunnissa. Jyry Suvilehto

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Taulukot & Periytyminen

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

12. Monimuotoisuus 12.1

public static void main (String [] args)

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä

1 Tehtävän kuvaus ja analysointi

Java-kielen perusteet

Rinnakkaisohjelmointi kurssi. Opintopiiri työskentelyn raportti

Poikkeusten ja tapahtumien käsittely

Informaatioteknologian laitos Olio-ohjelmoinnin perusteet / Salo

Periytyminen (inheritance)

Ohjelmoinnin perusteet, kurssikoe

Taulukoiden käsittely Javalla

Ohjelmointityö 3. Mikko Laamanen

11. Javan valintarakenteet 11.1

17. Javan omat luokat 17.1

// Tulostetaan double-tyyppiseen muuttujaan "hinta" tallennettu // kertalipun hinta ja vaihdetaan riviä. System.out.printf("%.1f euros.

Tietokannat II -kurssin harjoitustyö

Tietorakenteet. JAVA-OHJELMOINTI Osa 5: Tietorakenteita. Sisällys. Merkkijonot (String) Luokka String. Metodeja (public)

Pakkauksen kokoaminen

Javan perusteita. Janne Käki

812341A Olio-ohjelmointi Peruskäsitteet jatkoa

Ohjelmointi 2 / 2010 Välikoe / 26.3

Rajapinnasta ei voida muodostaa olioita. Voidaan käyttää tunnuksen tyyppinä. Rajapinta on kuitenkin abstraktia luokkaa selvästi abstraktimpi tyyppi.

KOHDELUOKAN MÄÄRITTELY

Sisällys. JAVA-OHJELMOINTI Osa 6: Periytyminen ja näkyvyys. Luokkahierarkia. Periytyminen (inheritance)

19. Olio-ohjelmointia Javalla 19.1

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

2. Olio-ohjelmoinista lyhyesti 2.1

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op. Tietorakenneluokkia 2: HashMap, TreeMap

12. Monimuotoisuus 12.1

Lohkot. if (ehto1) { if (ehto2) { lause 1;... lause n; } } else { lause 1;... lause m; } 15.3

List-luokan soveltamista. Listaan lisääminen Listan läpikäynti Listasta etsiminen Listan sisällön muuttaminen Listasta poistaminen Listan kopioiminen

Ohjelmoinnin perusteet Y Python

Tietojen syöttäminen ohjelmalle. Tietojen syöttäminen ohjelmalle Scanner-luokan avulla

Ohjelmoinnin perusteet Y Python

Sisällys. 11. Rajapinnat. Johdanto. Johdanto

5. HelloWorld-ohjelma 5.1

Java ja grafiikka. Ville Sundberg

Taulukot. Jukka Harju, Jukka Juslin

Pakkauksen kokoaminen

Harjoitus 5 (viikko 48)

Lista luokan sisällä

12. Javan toistorakenteet 12.1

Java-kielen perusteet

4. Luokan testaus ja käyttö olion kautta 4.1

Sisällys. 19. Olio-ohjelmointia Javalla. Yleistä. Olioiden esittely ja alustus

Transkriptio:

Sisällys 14. Poikkeukset Johdanto. Tarkistettavat ja tarkistamattomat poikkeukset. Miten varautua poikkeukseen metodissa? Poikkeusten tunnistaminen ja sieppaaminen try-catchlauseella. Mitä tehdä siepatulla poikkeuksella?. Exception-luokan metodeja. 14.1 14.2 Johdanto Ohjelman ajon aikana ilmennyt virhe pysäyttää ohjelman ellei virheeseen ole varattu asianmukaisesti. Ohjelman kaatuminen ei ole toivottavaa, koska siitä on aina harmia käyttäjälle. Jos virheestä ei voi toipua, tulisi ohjelman kaatumisen kuitenkin tapahtua hallitusti. Perinteiset tavat käsitellä ajonaikaisia virheitä: Tunnistetaan ja vältetään, mutta ei reagoida muuten. Tunnistetaan ja vältetään ja virheestä ilmoitetaan metodin paluuarvon avulla, jolloin metodia kutsuva metodi voi tarvittaessa reagoida virheeseen. 14.3 Johdanto Javassa virheen voidaan antaa myös tapahtua, koska virheen tuottama poikkeus (exception) voidaan tunnistaa ja siepata try-catch-lauseella. Poikkeusta ei voida jättää täysin huomiotta: Ohjelman suoritus pysähtyy, mikäli try-catch ei ole viimeistään main-metodissa. Poikkeukset on mallinnettu Javan API:ssa luokiksi, joista osa on jo tuttuja: NullPointerException: kutsutaan olion piirrettä null-arvoisen viitteen kautta. ArrayIndexOutOfBoundsException: viitataan virheelliseen paikkaan taulukossa. InputMismatchException: väärän tyyppinen syöte. 14.4

Exception-luokka Suuri osa poikkeuksista on Exception-luokan jälkeläisiä, jotka jaetaan tarkistamattomiin (unchecked) ja tarkistettaviin (checked) poikkeuksiin sen mukaan onko poikkeukseen pakko reagoida sen ollessa mahdollinen. Käytännössä myös tarkistamattomat poikkeukset on käsiteltävä jollain tavoin try-catch-lauseella, jotta ohjelma ei kaatuisi hallitsemattomasti, vaikka on kiistanalaista tulisiko ja voiko tarkistamattomiin poikkeuksiin ylipäätänsä reagoida. Java pakottaa ohjelmoijan joko kirjoittamaan try-catch-lauseen tai määrittelemään metodin otsikossa, että metodi voi heittää tarkistettavan poikkeuksen, jos metodissa kutsuttava metodi voi heittää tarkistettavan poikkeuksen. Exception-luokka RuntimeException-luokan ja sen jälkeläisluokkien mallintamat poikkeukset ovat tarkistamattomia. Exception-luokan muiden jälkeläisten poikkeukset ovat tarkistettavia. Error-luokan periytymishaara mallintaa vakavat, virtuaalikoneen toimintaan liittyvät virheet, joita ei yleensä ole syytä käsitellä. Pieni osa Exception-luokan sisältävästä luokkahierarkiasta. Exception RuntimeException NullPointerException Object Throwable Error IOException 14.5 14.6 Miten varautua poikkeukseen metodissa? Ei tehdä juuri mitään, vaan annetaan metodin heittää poikkeus automaattisesti. Poikkeuksen heittämisestä on kerrottava metodin yleisissä kommenteissa. Tarkistettavan poikkeuksen heittämisestä on pakko kertoa myös metodin otsikossa. Siepataan poikkeus trycatch-lauseella. Siepattu poikkeus voidaan käsitellä sopivaksi katsotulla tavalla paikallisesti catchlohkossa. Poikkeus voidaan heittää metodista sieppauksen jälkeen. Siepattuun poikkeukseen voidaan myös reagoida heittämällä uusi poikkeus. Poikkeuksen mahdollisesti tuottavat lauseet suljetaan trylohkoon mielellään niin, ettei koodin luettavuus kärsi. Poikkeuksen tapahtuessa catchlohkot tarkastellaan järjestyksessä ylhäältä alas. Poikkeus siepataan ensimmäiseen sen tyyppiä vastaavaan catch-lohkoon. Lohkon otsikossa annettu viite liittyy olioon, jonka on viitteen tai sen jälkeläisluokan tyyppiä. // Poikkeuksen mahdollisesti // tuottavat lauseet. catch (Tyyppi1 e) { // Tyypin1 poikkeusten käsittely. catch (TyyppiN e) { // TyypinN poikkeusten käsittely. 14.7 14.8

Exception-tyyppisellä parametrilla varustettu catchlohko sieppaa lähes minkä tahansa poikkeuksen. Käytettävä varovasti, koska voi estää virheiden havaitsemisen. Finally-lohko on valinnainen ja sen lauseet suoritetaan aina poikkeuksen tapahtumisesta riippumatta. Ohjelman suoritus jatkuu trycatch-lausetta seuraavasta lauseesta. // Poikkeuksen mahdollisesti // tuottavat lauseet. catch (Tyyppi1 e) { // Tyypin1 poikkeusten käsittely. catch (Exception e) { // Siepataan viimeistään tässä. finally { // Tämä lohko suoritetaan aina. Javan versiosta 1.7 alkaen catch-lohkoon voi määritellä siepattavaksi useampia virheitä putkimerkin avulla. Toinen uudistus on resursoitu try-catch-lause, jota voidaan käyttää finallylohkon tapaan varattujen resurssien vapauttamiseen ne sulkemalla. Resurssi varataan luomalla olio AutoCloseable-rajapinnan toteuttavasta luokasta. catch (Tyyppi1 Tyyppi2 e) { // Molemman tyyppisten // poikkeusten käsittely. try (resurssien varaaminen) { // Lukija suljetaan ennen mahdollisen // virheen sieppausta. try (Scanner sc = new Scanner(new File( in.txt ))) { catch () { 14.9 14.10 Scanner & InputMismatchException import java.util.*; // Scanner-luokka on täällä. public class InputMismatchExceptionTest { public static void main(string[] args) { Scanner sc = new Scanner(System.in); // Liitetään oletussyötevirtaan. int luku; boolean syoteok; do { // Luetaan, kunnes saadaan kokonaisluku. // Tämän lohkon aiheuttamat poikkeukset siepataan. syoteok = true; System.out.println("Anna luku:"); luku = sc.nextint(); // Väärän tyyppinen syöte => poikkeus. catch (InputMismatchException e) { // Siepataan poikkeus. System.out.println("Virheellinen syöte!"); sc.nextline(); // Poistetaan virheellinen syöte. syoteok = false; while (!syoteok); 14.11 Mitä tehdä siepatulla poikkeuksella? Kun poikkeus käsitellään paikallisesti, siitä tiedetään kutsuvassa metodissa korkeintaan paluuarvon kautta. Käsittely voi olla esimerkiksi virhetulostus, resurssien vapauttaminen tai paluuarvon asettaminen. Poikkeus on mahdollista antaa tiedoksi kutsuvalle metodille heittämällä se throw-lauseella. catch (IOException e) { // Heitetään siepattu poikkeus. throw e; 14.12

Siepattuun virheeseen on myös mahdollista reagoida luomalla ja heittämällä uusi poikkeus. catch (FileNotFoundException e) { throw new IllegalArgumentException( Virheellinen nimi. ); Heittäminen voidaan yhdistää parametrien tarkistukseen. Virheellinen arvo tunnistetaan perinteisesti if-lauseella, mutta virheeseen reagoidaan paluuarvon sijasta heittämällä poikkeus, joka on usein IllegalArgumentException-tyyppiä. if (tiedostonnimi == null tiedostonnimi.length() == 0) { throw new IllegalArgumentException( Virheellinen nimi. ); 14.13 Metodin otsikossa on määriteltävä throws-ilmauksella metodin heittämät tarkistettavat poikkeukset. metodinnimi(parametrilista) throws Poikkeus1, Poikkeus2, { Tarkistamattomia poikkeuksia ei ole pakko määritellä, mutta yleisissä kommenteissa on hyvä mainita myös poikkeukset, jotka palautuvat automaattisesti ilman heittämistä. Kutsuvassa metodissa on syytä varautua poikkeuksiin, kun kutsuttavan metodin otsikossa esiintyy throws-ilmaus. Java pakottaa kutsuvan metodin tähän, jos metodi heittää tarkistettavan poikkeuksen. 14.14 Rakentaja ei voi palauttaa virhekoodeja, mutta rakentajakin voi heittää tarvittaessa poikkeuksen: public Kissa(String v, String h) throws IllegalArgumentException { if (v == null h == null ) { throw new IllegalArgumentException(); else 14.15 /* Lasketaan taulukon t paikoissa [a, b] olevien alkioiden summa. Paluuarvo on * Double.NaN, jos parametreissa oli virhe. public static double laskevalinsumma(double[] t, int a, int b) { // Tässä lohkossa voi tapahtua poikkeuksia. // Indeksiarvot a ja/tai b olivat virheellisiä. catch (ArrayIndexOutOfBoundsException e) { // Taulukolle ei oltu varattu muistia (t == null). catch (NullPointerException e) { return summa; Parametrien tarkistus pelkästään poikkeuksiin tukeutuen voi olla vaillinaista. Tässä esimerkissä poikkeusta ei voi tapahtua, kun a > b. 14.16

/* Lasketaan taulukon t paikoissa [a, b] olevien alkioiden summa. Heittää * IllegalArgumentException-tyyppisen poikkeuksen, jos taulukon käsittelyssä * tapahtui virhe. public static double laskevalinsumma(double[] t, int a, int b) throws IllegalArgumentException { return summa; catch (Exception e) { throw new IllegalArgumentException(e); 14.17 public static void main(string[] args) { double summa1, summa2; // Siepataan laskevalinsumma-metodin mahdolliset poikkeukset. double[] t1 = new double[] { 1.1, 2.2, 3.3, 4.4, 5.5 ; // Virheellinen indeksi tuottaa ArrayIndexOutOfBoundsException-poikkeuksen. summa = laskevalinsumma(t1, 0, 5); // Taulukolle ei oltu varattu muistia (t == null) tai indeksiarvo(t) oli(vat) virheellisiä. catch (IllegalArgumentException e) { // java.lang.illegalargumentexception: java.lang.arrayindexoutofboundsexception: 5 System.out.println(e); 14.18 Exception-luokan metodeja Perii joitakin hyödyllisiä metodeja yliluokastaan: PrintStackTrace: Tulostaa standardivirhevirtaan (oletusarvoisesti näytölle) virtuaalikoneen luoman virheilmoituksen. Ilmoitus on lähes sama kuin Javan ajonaikaisen virheen vuoksi tulostama virheilmoitus. On suureksi avuksi, kun on tarpeen selittää missä catch-lohkoon siepattu virhe tapahtui. GetStackTrace: Palauttaa StackTraceElement-luokan viitteen, jonka kautta poikkeuksen tietoja voidaan tutkia tarkemmin. ToString: Palauttaa poikkeusta kuvailevan merkkijonon. Ohjelmoija voi periä omia poikkeusluokkia. 14.19 /* Lasketaan taulukon t paikoissa [a, b] olevien alkioiden summa. public static double laskevalinsumma(double[] t, int a, int b) { // Tässä lohkossa voi tapahtua poikkeuksia. // Indeksiarvot a ja/tai b olivat virheellisiä. catch (ArrayIndexOutOfBoundsException e) { java.lang.arrayindexoutofboundsexception: 5 System.out.println(e.toString()); // Taulukolle ei oltu varattu muistia (t == null). catch (NullPointerException e) { e.printstacktrace(); java.lang.nullpointerexception at TaulukkoPoikkeusDemo3.laskeValinsumma(TaulukkoPoikkeusDemo3.java:16) at TaulukkoPoikkeusDemo3.main(TaulukkoPoikkeusDemo3.java:33) 14.20