Kuinka käsitellä Java -poikkeuksia oikein

Kuinka käsitellä Java -poikkeuksia oikein

Ohjelmoinnin aloittelijana käsite poikkeusten käsittely voi olla vaikea kääntää päätäsi. Ei sillä, että käsite itsessään olisi vaikea, mutta terminologia voi saada sen näyttämään kehittyneemmältä kuin se on. Ja se on niin voimakas ominaisuus, että se on altis väärinkäytölle ja väärinkäytölle.





Tässä artikkelissa opit, mitä poikkeukset ovat, miksi ne ovat tärkeitä, miten niitä käytetään ja mitä yleisiä virheitä kannattaa välttää. Useimmilla nykyaikaisilla kielillä on jonkinlainen poikkeusten käsittely, joten jos siirryt Javasta, voit ottaa suurimman osan näistä vinkeistä mukaasi.





Java -poikkeusten ymmärtäminen

Javassa an poikkeus on kohde, joka osoittaa jotain epänormaalia (tai 'poikkeuksellista') sovelluksesi suorittamisen aikana. Tällaisia ​​poikkeuksia on heitetty , joka pohjimmiltaan tarkoittaa poikkeusobjektin luomista (samanlainen kuin virheiden 'nostaminen').





Kauneus on se, että voit saada kiinni poikkeuksia, joiden avulla voit käsitellä epänormaalia tilaa ja antaa sovelluksesi jatkaa toimintaansa ikään kuin mikään ei olisi mennyt pieleen. Esimerkiksi kun nollapiste C: ssä voi kaataa sovelluksesi, Java antaa sinun heittää ja ottaa kiinni

NullPointerException

s ennen kuin nollamuuttujalla on mahdollisuus aiheuttaa kaatuminen.



Muista, että poikkeus on vain esine, mutta sillä on yksi tärkeä ominaisuus: sitä on laajennettava

Exception

luokka tai mikä tahansa sen alaluokka





Exception

. Vaikka Javalla on kaikenlaisia ​​sisäänrakennettuja poikkeuksia, voit myös luoda omia, jos haluat. Jotkut yleisimmät Java -poikkeukset sisältää:

  • NullPointerException
  • NumberFormatException
  • IllegalArgumentException
  • RuntimeException
  • IllegalStateException

Mitä sitten tapahtuu, kun teet poikkeuksen?





Ensinnäkin Java etsii välittömästä menetelmästä nähdäkseen, onko olemassa koodia, joka käsittelee heittämääsi poikkeusta. Jos käsittelijää ei ole olemassa, se tarkastelee nykyistä menetelmää kutsunutta menetelmää nähdäkseen, onko kahva olemassa. Jos ei, se tarkastelee kutsuttua menetelmää että menetelmä ja sitten seuraava menetelmä jne. Jos poikkeusta ei havaita, sovellus tulostaa pinojäljen ja kaatuu. (Itse asiassa se on vivahteikkaampaa kuin yksinkertaisesti kaatuminen, mutta se on edistynyt aihe tämän artikkelin ulkopuolella.)

TO pinojälki on luettelo kaikista menetelmistä, jotka Java läpäisi etsiessään poikkeuskäsittelijää. Pinojälki näyttää tältä:

Exception in thread 'main' java.lang.NullPointerException
at com.example.myproject.Book.getTitle(Book.java:16)
at com.example.myproject.Author.getBookTitles(Author.java:25)
at com.example.myproject.Bootstrap.main(Bootstrap.java:14)

Tästä voimme poimia paljon. Ensinnäkin heitetty poikkeus oli a

NullPointerException

. Se tapahtui

getTitle()

menetelmä Book.javan rivillä 16. Tämä menetelmä on kutsuttu

getBookTitles()

Author.javan rivillä 25. Että menetelmä on kutsuttu

main()

Bootstrap.javan rivillä 14. Kuten näette, tämän kaiken tietäminen helpottaa virheenkorjausta.

Mutta jälleen kerran, poikkeusten todellinen etu on, että voit 'käsitellä' epänormaalia tilaa ottamalla poikkeuksen, asettamalla asiat oikein ja jatkamalla sovellusta kaatumatta.

Java -poikkeusten käyttäminen koodissa

Oletetaan, että sinulla on

someMethod()

joka ottaa kokonaisluvun ja suorittaa jonkin logiikan, joka voi rikkoutua, jos kokonaisluku on pienempi kuin 0 tai suurempi kuin 100. Tämä voisi olla hyvä paikka tehdä poikkeus:

kotini historia osoitteen mukaan
public void someMethod(int value) {
if (value 100) {
throw new
IllegalArgumentException

Tämän poikkeuksen saamiseksi sinun on mentävä mihin

someMethod()

kutsutaan ja käytetään yrittää saalis lohko :

public void callingMethod() {
try {
someMethod(200);
someOtherMethod();
} catch (IllegalArgumentException e) {
// handle the exception in here
}
// ...
}

Kaikki sisällä yrittää lohko suoritetaan järjestyksessä, kunnes poikkeus heitetään. Heti kun poikkeus heitetään, kaikki seuraavat lausumat ohitetaan ja sovelluslogiikka hyppää välittömästi kohtaan saada kiinni lohko.

Esimerkissämme annamme kokeilulohkon ja soitamme heti

someMethod()

. Koska 200 ei ole välillä 0 ja 100, an

IllegalArgumentException

heitetään. Tämä lopettaa välittömästi suorituksen

someMethod()

, ohittaa loput logiikasta try -lohkossa (

someOtherMethod()

ei koskaan kutsuta), ja jatkaa suoritusta saalislohkossa.

Mitä tapahtuisi, jos soittaisimme

someMethod(50)

sen sijaan? The

IllegalArgumentException

ei koskaan heitettäisi.

someMethod()

toimisi normaalisti. Kokeilulohko toimisi normaalisti kutsuen

someOtherMethod()

kun someMethod () on valmis. Kun

someOtherMethod()

päättyy, saalislohko ohitetaan ja

callingMethod()

jatkuisi.

Huomaa, että voit saada useita saalislohkoja kokeilulohkoa kohden:

public void callingMethod() {
try {
someMethod(200);
someOtherMethod();
} catch (IllegalArgumentException e) {
// handle the exception in here
} catch (NullPointerException e) {
// handle the exception in here
}
// ...
}

Huomaa myös, että valinnainen vihdoin lohko on myös olemassa:

public void method() {
try {
// ...
} catch (Exception e) {
// ...
} finally {
// ...
}
}

Lopullisen lohkon koodi on aina teloitettiin mitä tahansa. Jos kokeilulauseessa on palautuslauseke, lopullinen lohko suoritetaan ennen kuin palataan menetelmästä. Jos heität toisen poikkeuksen saalislohkoon, lopullinen lohko suoritetaan ennen kuin poikkeus heitetään.

Käytä lopullista lohkoa, kun sinulla on esineitä, jotka on puhdistettava ennen menetelmän päättymistä. Jos esimerkiksi avasit tiedoston kokeiluryhmässä ja heitit myöhemmin poikkeuksen, lopullisen lohkon avulla voit sulkea tiedoston ennen menetelmän poistumista.

Huomaa, että voit saada lopullisen lohkon ilman saalislohkoa:

public void method() {
try {
// ...
} finally {
// ...
}
}

Tämän avulla voit tehdä tarvittavat puhdistukset samalla, kun heitetyt poikkeukset levittävät menetelmäkutsupinoa (eli et halua käsitellä poikkeusta täällä, mutta sinun on silti siivottava ensin).

Tarkistetut ja tarkistamattomat poikkeukset Javassa

Toisin kuin useimmat kielet, Java erottaa toisistaan tarkistetut poikkeukset ja tarkistamattomat poikkeukset (esim. C# sisältää vain tarkistamattomat poikkeukset). Tarkistettu poikkeus on pakko olla kiinni menetelmässä, jossa poikkeus heitetään, tai muuten koodi ei käänny.

Jos haluat luoda tarkistetun poikkeuksen, laajenna

Exception

. Jos haluat luoda tarkistamattoman poikkeuksen, laajenna

RuntimeException

.

Kaikkien menetelmien, jotka heittävät tarkistetun poikkeuksen, on osoitettava tämä menetelmän allekirjoituksessa käyttämällä heittää avainsana. Koska Java on sisäänrakennettu

IOException

on valittu poikkeus, seuraava koodi ei käänny:

public void wontCompile() {
// ...
if (someCondition) {
throw new IOException();
}
// ...
}

Sinun on ensin ilmoitettava, että se tekee tarkistetun poikkeuksen:

public void willCompile() throws IOException {
// ...
if (someCondition) {
throw new IOException();
}
// ...
}

Huomaa, että menetelmä voidaan julistaa poikkeukseksi, mutta ei koskaan heittää poikkeusta. Siitä huolimatta poikkeus on silti pyydettävä, tai muuten koodi ei käänny.

Milloin kannattaa käyttää tarkistettuja tai tarkistamattomia poikkeuksia?

Virallisessa Java -dokumentaatiossa on sivulla tästä kysymyksestä . Se tiivistää eron ytimekkäällä nyrkkisääntönä: ”Jos asiakkaan voidaan kohtuudella odottaa toipuvan poikkeuksesta, tee siitä tarkistettu poikkeus. Jos asiakas ei voi tehdä mitään toipuakseen poikkeuksesta, tee siitä tarkistamaton poikkeus. ''

Mutta tämä ohje voi olla vanhentunut. Toisaalta tarkistetut poikkeukset johtavat vahvempaan koodiin. Toisaalta mikään muu kieli ei ole tarkistanut poikkeuksia samalla tavalla kuin Java, mikä osoittaa kaksi asiaa: yksi, ominaisuus ei ole tarpeeksi hyödyllinen muille kielille varastaakseen sen, ja kaksi, voit elää ilman niitä. Lisäksi tarkistetut poikkeukset eivät pelaa hienosti Java 8: ssa käyttöön otettujen lambda -lausekkeiden kanssa.

Ohjeita Java -poikkeusten käyttöön

Poikkeukset ovat hyödyllisiä, mutta helposti väärin ja väärin. Seuraavassa on muutamia vinkkejä ja parhaita käytäntöjä, jotka auttavat sinua välttämään sotkua.

  • Käytä erityisiä poikkeuksia yleisiin poikkeuksiin nähden. Käytä | _+_ | yli | _+_ | jos mahdollista, käytä muuten | _+_ | yli | _+_ | kun mahdollista.
  • Älä koskaan saa kiinni | _+_ | ! | _+_ | luokka todella ulottuu | _+_ | , ja saalislohko todella toimii | _+_ | tai mikä tahansa luokka, joka laajentaa heitettävää. Kuitenkin | _+_ | luokka ulottuu myös | _+_ | , etkä koskaan halua saada | _+_ | koska | _+_ | osoittavat vakavia korjaamattomia ongelmia.
  • Älä koskaan saa kiinni | _+_ | ! | _+_ | ulottuu | _+_ | , joten mikä tahansa lohko, joka tarttuu | _+_ | saa myös | _+_ | , ja se on erittäin tärkeä poikkeus, jota et halua sekoittaa (varsinkin monisäikeisissä sovelluksissa), ellet tiedä mitä olet tekemässä. Jos et tiedä, mikä poikkeus pyydetään sen sijaan, älä ota kiinni mitään.
  • Käytä kuvaavia viestejä helpottaaksesi virheenkorjausta. Kun heität poikkeuksen, voit antaa | _+_ | viesti argumenttina. Tämä viesti on käytettävissä saalislohkossa käyttämällä | _+_ | menetelmä, mutta jos poikkeusta ei koskaan saada kiinni, viesti näkyy myös osana pinojälkeä.
  • Yritä olla kiinni ja sivuuttaa poikkeukset. Jotta vältetään tarkistettujen poikkeusten aiheuttamat haitat, monet aloittelijat ja laiskoja ohjelmoijia asettavat saalislohkon, mutta jättävät sen tyhjäksi. Huono! Käsittele sitä aina tyylikkäästi, mutta jos et pysty, tulosta ainakin pinojälki, jotta tiedät, että poikkeus heitettiin. Voit tehdä tämän käyttämällä | _+_ | menetelmä.
  • Varo poikkeusten liiallista käyttöä. Kun sinulla on vasara, kaikki näyttää naulalta. Kun opit ensimmäistä kertaa poikkeuksista, saatat tuntea velvollisuutesi muuttaa kaikki poikkeukseksi ... siihen pisteeseen, että suurin osa sovelluksesi ohjausvirrasta tulee poikkeusten käsittelyyn. Muista, että poikkeukset on tarkoitettu 'poikkeuksellisiin' tapahtumiin!

Nyt sinun pitäisi olla tarpeeksi mukava poikkeuksia lukuun ottamatta ymmärtää, mitä ne ovat, miksi niitä käytetään ja miten voit sisällyttää ne omaan koodiin. Jos et ymmärrä konseptia täysin, se ei haittaa! Kesti jonkin aikaa, ennen kuin se 'napsautti' päässäni, joten älä tunne, että sinun pitäisi kiirehtiä sitä. Ei kiirettä.

Onko sinulla kysyttävää? Tiedätkö muita poikkeuksiin liittyviä vinkkejä, jotka olen unohtanut? Jaa ne alla oleviin kommentteihin!

Jaa Jaa Tweet Sähköposti Kuinka luoda datavirtakaavio minkä tahansa projektin tietojen visualisoimiseksi

Minkä tahansa prosessin datavirtakaaviot (DFD) auttavat sinua ymmärtämään, miten tiedot kulkevat lähteestä kohteeseen. Näin voit luoda sen!

Lue seuraava
Liittyvät aiheet
  • Ohjelmointi
  • Java
Kirjailijasta Joel Lee(1524 artikkelia julkaistu)

Joel Lee on toiminut MakeUseOfin päätoimittajana vuodesta 2018. Hänellä on B.S. tietojenkäsittelytieteen alalta ja yli yhdeksän vuoden ammattikirjoittamisesta ja editoinnista.

403 kielletty, sinulla ei ole lupaa käyttää / tällä palvelimella
Lisää Joel Leelta

tilaa uutiskirjeemme

Liity uutiskirjeeseemme saadaksesi teknisiä vinkkejä, arvosteluja, ilmaisia ​​e -kirjoja ja ainutlaatuisia tarjouksia!

Klikkaa tästä tilataksesi