Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Java: try...catch

Sivun loppuun

Tumettaja [12.05.2010 15:23:00]

#

Koodini näyttää tältä:

try {
   while (tarkista()) {
      //tässä tehdään jotain
   }
} catch (Exception e) {}

Kysymys kuuluukin mitä tapahtuu jos while-silmukassa tapahtuu virhe ja tuo try...catch rakenne nappaa sen virheen? Jääkö while-silmukka pyörimään kunnes itse sen jollain tavalla lopetan? Ja jos ei, onko mitään keinoa saada se jäämään pyörimään?

Chiman [12.05.2010 15:27:40]

#

Ei jää pyörimään, mutta näin jäisi:

while (tarkista()) {
   try {
      // tässä tehdään jotain
   } catch (Exception e) {}
}

Tumettaja [12.05.2010 15:30:27]

#

Mutta mitäs sitten jos tuo tarkista()-metodikin voi heittää virhettä? Jos se aiheuttaa virheen niin sehän jää nyt käsittelemättä jos oikein ymmärsin?

Chiman [12.05.2010 15:32:04]

#

Miten koodin pitäisi käyttäytyä, jos tarkista() heittää virheen? Jatkaa whilen pyörittämistä?

Muoks: Jos kyllä, niin tässä yksi keino näillä puutteellisilla tiedoilla:

while (true) {
   try {
      if (!tarkista()) {
         break;
      }
      // tässä tehdään jotain
   } catch (Exception e) {}
}

Tumettaja [12.05.2010 15:39:50]

#

Kyllä eli while-silmukan pitäisi pyöriä niin kauan kunnes tarkista()-metodi palauttaa falsen ja virhe ei saisi häiritä tätä while-silmukan pyörimistä.

Chiman [12.05.2010 15:44:12]

#

Antamani koodi ei pyöritä while-silmukan muuta sisältöä, jos tarkista() heittää virhettä, mutta osaat varmasti muokata sitä itse tarpeen mukaan.

Teuro [12.05.2010 17:30:21]

#

Nähdäkseni koodisi ei ole oikein suunniteltu, koska tuossa osassa ollessaa try...catch rakenne tutkii juurikin while silmukan heittämiä virheitä. Tuossahan heitetty virhe on juurikin niin fataali, että silmukan jatko ei ole mielekästä. Esimerkiksi välitulokseen tulisi nollalla jako tai vastaavaa.

Silmukan jatkaminen olisi mahdolisesti toteutettavissa continue käskyllä, jolloin silmukan loppu jätetään käsittelemättä, mutta aloitetaan kuitenkin uusi kierros. Virheiden heittämisen tarkoitus ei ole virheiden kiertäminen, vaan niistä toipuminen. Virhe tulisikin kaiketi heittää juurikin silloin, kun jatkaminen ei ole mielekästä.

Macro [12.05.2010 20:40:07]

#

Tumettaja kirjoitti:

Kyllä eli while-silmukan pitäisi pyöriä niin kauan kunnes tarkista()-metodi palauttaa falsen ja virhe ei saisi häiritä tätä while-silmukan pyörimistä.

Mitäs himpskattia? Eli, kun tulee virhe sen pitäisi pysähtyä, mutta ei sittenkään saisi pysähtyä?

"while-silmukan pitäisi pyöriä niin kauan kunnes tarkista()-metodi palauttaa falsen"

Eli virheen tullessa lopetettaisiin käsittely.

"ja virhe ei saisi häiritä tätä while-silmukan pyörimistä"

Eli virheestä huolimatta jatkettaisiin.

Kumman nyt haluat?

while(true) {
   if(!tarkista()) {
      // tarkista() palautti falsen, lopetetaan koko silmukka
      break;
   }

   // Muutoin jatketaan pyörimistä...
}
while(true) {
   if(!tarkista()) {
      // tarkista() palautti falsen, lopetetaan tämä kierros
      continue;
   }

   // Muutoin jatketaan pyörimistä...
}

Metabolix [12.05.2010 21:24:52]

#

Macro, virheellä viitattiin siihen kolmanteen vaihtoehtoon, jossa funktio ei palauta mitään vaan suoritus hyppää catch-lohkoon.

Jos oikeasti olet sitä mieltä, että tarkistuksessa tapahtuva virhe ei saa keskeyttää silmukkaa, selkein ratkaisu olisi tehdä erillinen funktio, joka käsittelisi tarkista-funktion poikkeuksen ja palauttaisi sen lopullisen päätöksen.

boolean tarkista_oikeasti() {
    while (true) {
        try {
            return tarkista();
        } catch (Exception e) {
            // Virhe; silmukka jatkuu, tarkistetaan uudestaan.
            // Voitaisiin myös palauttaa suoraan true tai false.
        }
    }
}

// Oikea silmukka; tarkista_oikeasti ei heitä poikkeusta.
// Lisää try-lohko haluamaasi paikkaan.
while (tarkista_oikeasti()) {
    // ...
}

Macro [12.05.2010 21:52:50]

#

Mutta, jollei funktio palauta mitään, niin if-lauseessa se käsitellään falsena.

Chiman [12.05.2010 21:58:57]

#

Macro kirjoitti:

Mutta, jollei funktio palauta mitään, niin if-lauseessa se käsitellään falsena.

Väärin. Poikkeus keskeyttää funktion suorituksen ennen kuin siitä poistutaan normaalisti. Tällöin kyseinen funktio ei palauta mitään, eikä if-lauseen sisältöä selvitetä, vaan suoritus hyppää sopivaan catch-lohkoon (tai jos sellaista ei löydy miltään tasolta, ohjelman suoritus päättyy).

Muoks: Sekoitatkohan Pythoniin, jossa return-lauseen puuttuminen vastaa samaa kuin return None? Silti poikkeukset käyttäytyvät samoin siinäkin, eli suoritus hyppää aivan eri kohtaan, eikä funktiosta poistuta niin että sen paluuarvoa tulkittaisiin millään tavalla.

Metabolix [12.05.2010 22:10:31]

#

Macro kirjoitti:

Mutta, jollei funktio palauta mitään, niin if-lauseessa se käsitellään falsena.

Javassa ei edes ole mahdollista tehdä funktiota, joka ei palauttaisi sitä, mitä sen etukäteen on ilmoitettu palauttavan (tässä true tai false). Kääntäjä tarkistaa, että funktiosta löytyy joka tilanteessa return-lause (tai throw-rivi, jos nyt sille linjalle lähdetään; Chiman tästä jo selittikin).

Varmaan ajattelet nyt PHP:tä tai muita skriptikieliä, joissa "ei mitään" tarkoittaa yleensä samaa kuin null- tai None-arvon palauttaminen. Sen sijaan vaikkapa C:ssä return-lauseen puuttumisesta seuraa, että funktion paluuarvoksi tulee suhteellisen satunnainen arvo tietokoneen muistista.

Macro [13.05.2010 09:26:37]

#

Juu, en ole koskaan Javaa ohjelmoinut, niin ajattelin sen käyttäytyvän kuten Python ja PHP.

FooBat [17.05.2010 22:45:55]

#

Jos tarkista-metodissa tapahtuu virhetilanteita, joista pystytään selviämään, on oikea paikka käsitellä nämä virheet tuon metodin sisällä. On hyvin kyseenalaista, että tällainen tarkistus-metodi heittää ulos mitään hallittavia virheitä. Kriittiset RuntimeException ovat asia erikseen ja niitä ei todennäköisesti kannattaisi hallita tällä tasolla.

boolean tarkista() {
   try {
      //Normaali tarkistuskoodi
      //return true/false
      ...
   }
   catch (IOException e) {
      //Hallittu virhe, pahaksi havaittu virhetilanne, silmukka ei jatku
      return false;
   }
   catch (Exception e) {
      //Hallittu virhe, tuntematon virhetilanne, sormet ristiin, silmukka jatkuu
      return true;
   }
}

hk [19.05.2010 00:10:29]

#

Taas kerran kannattaisi näyttää ihan oikea konkreettinen koodi, jotta saa oikeita vastauksia. Jos ei osaa ratkaista ongelmaa, osaa harvoin myöskään esittää algoritmia karsittuna niin, että kaikka asiaan vaikuttavat tekijät siinä edelleen näkyvät. Tumettaja ehkä vaan yrittää tehdä jotain, mitä ei pitäisi lainkaan tehdä, tai sitten ongelmaan on helppo ratkaisu. Anna Tumettaja todellinen koodi, niin saat neuvoja kuinka se kannattaa toteuttaa.

Yleisesti ottaenhan metodi aina kirjoitetaan niin, ettei virhettä voi tapahtua, siis tarkastetaan parametrit. Sitten on tilanteita, kuten vaikkapa tietokantaoperaatiot, joissa voi tapahtua virhe. Silloin päätetään kuinka toimitaan, jos virhe tapahtuu, usein se on fataali, eli voidaan yrittää joku kerta uudestaan, mutta jos ei sittenkään onnistu, niin hyväksytään tilanne. Yleensä ko. tapauksessa jo yksi epäonnistuminen aiheuttaa ohjelman keskeytyksen, mutta on toki ongelmia, jotka poistuvat ajan myötä, ja sitten voidaan jatkaa. Tuskin koskaan voidaan jäädä loputtomiin yrittämään, että jos nyt homma toimisi.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta