CodeGym /Java-blogg /Tilfeldig /Unntak i Java
John Squirrels
Nivå
San Francisco

Unntak i Java

Publisert i gruppen
Hallo! I dagens leksjon skal vi snakke om Java-unntak. Hverdagen er full av situasjoner som vi ikke forutser. Du står for eksempel opp på jobb om morgenen og ser etter telefonladeren din, men du finner den ikke noe sted. Du går på do for å dusje bare for å oppdage at rørene er frosne. Du setter deg i bilen, men den starter ikke. Et menneske er i stand til å takle slike uforutsette omstendigheter ganske enkelt. I denne artikkelen skal vi prøve å finne ut hvordan Java-programmer håndterer dem.

Hva er et Java-unntak?

I programmeringsverdenen kalles feil og uforutsette situasjoner i gjennomføringen av et program unntak. I et program kan unntak oppstå på grunn av ugyldige brukerhandlinger, utilstrekkelig diskplass eller tap av nettverksforbindelsen til serveren. Unntak kan også skyldes programmeringsfeil eller feil bruk av en API. I motsetning til mennesker i den virkelige verden, må et program vite nøyaktig hvordan det skal håndtere disse situasjonene. For dette har Java en mekanisme kjent som unntakshåndtering.

Noen få ord om nøkkelord

Unntakshåndtering i Java er basert på bruk av følgende nøkkelord i programmet:
  • try - definerer en kodeblokk der et unntak kan forekomme;
  • catch - definerer en kodeblokk der unntak håndteres;
  • til slutt - definerer en valgfri kodeblokk som, hvis den er til stede, utføres uavhengig av resultatene av prøveblokken.
Disse søkeordene brukes til å lage spesielle konstruksjoner i koden: prøv{}fangst , prøv{}fang{}til slutt , prøv{}til slutt{} .
  • kaste - brukes til å heve et unntak;
  • throws - brukes i metodesignaturen for å advare om at metoden kan gi et unntak.
Et eksempel på bruk av nøkkelord i et Java-program:

// This method reads a string from the keyboard

public String input() throws MyException { // Use throws to warn 
// that the method may throw a MyException
      BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String s = null;
// We use a try block to wrap code that might create an exception. In this case,
// the compiler tells us that the readLine() method in the 
// BufferedReader class might throw an I/O exception
    try {
        s = reader.readLine();
// We use a catch block to wrap the code that handles an IOException  
    } catch (IOException e) {
        System.out.println(e.getMessage());
// We close the read stream in the finally block
    } finally {
// An exception might occur when we close the stream if, for example, the stream was not open, so we wrap the code in a try block
        try {
            reader.close();
// Handle exceptions when closing the read stream
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }

    if (s.equals("")) {
// We've decided that an empty string will prevent our program from working properly. For example, we use the result of this method to call the substring(1, 2) method. Accordingly, we have to interrupt the program by using throw to generate our own MyException exception type.
        throw new MyException("The string cannot be empty!");
    }
    return s;
}

Hvorfor trenger vi unntak?

La oss se på et eksempel fra den virkelige verden. Tenk deg at en del av en motorvei har en liten bro med begrenset vektkapasitet. Hvis en bil som er tyngre enn broens grense, kjører over den, kan den kollapse. Situasjonen for sjåføren ville bli mildt sagt eksepsjonell. For å unngå dette setter samferdselsavdelingen opp varselskilt på veien før noe går galt. Når en sjåfør ser varselskiltet, sammenligner han eller hennes kjøretøys vekt med maksimalvekten for broen. Hvis kjøretøyet er for tungt, tar sjåføren en omkjøringsrute. Transportavdelingen gjorde det for det første mulig for lastebilsjåfører å endre rute om nødvendig, for det andre advarte sjåførene om farene på hovedveien, og for det tredje advarte sjåførene om at broen ikke må brukes under visse forhold. Unntak i Java - 2Evnen til å forhindre og løse eksepsjonelle situasjoner i et program, slik at det kan fortsette å kjøre, er en grunn til å bruke unntak i Java. Unntaksmekanismen lar deg også beskytte koden (API) mot feil bruk ved å validere (sjekke) eventuelle inndata. Tenk deg nå at du er transportavdelingen for et sekund. Først må du vite stedene der bilistene kan forvente trøbbel. For det andre må du opprette og installere advarselsskilt. Og til slutt må du sørge for omveier hvis det oppstår problemer på hovedruten. I Java fungerer unntaksmekanismen på lignende måte. Under utvikling bruker vi en prøveblokk for å bygge en "unntaksbarrierer" rundt farlige deler av kode, vi tilbyr "backup-ruter" ved hjelp av en catch {}blokk, og vi skriver kode som skal kjøre uansett hva i en endelig{} blokk. Hvis vi ikke kan gi en «backup-rute» eller vi ønsker å gi brukeren rett til å velge, må vi i det minste advare vedkommende om faren. Hvorfor? Se for deg indignasjonen til en sjåfør som uten å se et eneste varselskilt når en liten bro som han ikke kan krysse! Når det gjelder programmering, når vi skriver våre klasser og metoder, kan vi ikke alltid forutse hvordan de kan brukes av andre utviklere. Som et resultat kan vi ikke forutse den 100 % riktige måten å løse en eksepsjonell situasjon på. Når det er sagt, er det en god måte å advare andre om muligheten for eksepsjonelle situasjoner. Javas unntaksmekanisme lar oss gjøre dette med kastenenøkkelord – i hovedsak en erklæring om at metodens generelle oppførsel inkluderer å kaste et unntak. Dermed vet alle som bruker metoden at han eller hun bør skrive kode for å håndtere unntak.

Advarer andre om "trøbbel"

Hvis du ikke planlegger å håndtere unntak i metoden din, men ønsker å advare andre om at unntak kan forekomme, bruk nøkkelordet throws . Dette nøkkelordet i metodesignaturen betyr at metoden under visse forhold kan gi et unntak. Denne advarselen er en del av metodegrensesnittet og lar brukerne implementere sin egen unntakshåndteringslogikk. Etter kast spesifiserer vi typene unntak som blir kastet. Disse stammer vanligvis fra Javas unntaksklasse . Siden Java er et objektorientert språk, er alle unntak objekter i Java. Unntak i Java - 3

Unntakshierarki

Når det oppstår en feil mens et program kjører, oppretter JVM et objekt av passende type fra Java-unntakshierarkiet - et sett med mulige unntak som stammer fra en felles stamfar - Throwable- klassen . Vi kan dele eksepsjonelle kjøretidssituasjoner i to grupper:
  1. Situasjoner der programmet ikke kan gjenopprette og fortsette normal drift.
  2. Situasjoner der utvinning er mulig.
Den første gruppen inkluderer situasjoner som involverer et unntak som stammer fra feilklassen . Dette er feil som oppstår på grunn av en JVM-feil, minneoverflyt eller systemfeil. De indikerer vanligvis alvorlige problemer som ikke kan fikses med programvare. I Java sjekkes ikke muligheten for slike unntak av kompilatoren, så de er kjent som ukontrollerte unntak. Denne gruppen inkluderer også RuntimeExceptions, som er unntak som stammer fra unntaketklasse og genereres av JVM under kjøring. De er ofte forårsaket av programmeringsfeil. Disse unntakene er heller ikke sjekket (ikke avmerket) på kompileringstidspunktet, så du er ikke pålagt å skrive kode for å håndtere dem. Den andre gruppen inkluderer eksepsjonelle situasjoner som kan forutses når du skriver programmet (og derfor bør du skrive kode for å håndtere dem). Slike unntak kalles sjekkede unntak. Når det gjelder unntak, er det meste av en Java-utviklers arbeid å håndtere slike situasjoner.

Oppretter et unntak

Når et program kjører, genereres unntak enten av JVM eller manuelt ved hjelp av en throw -setning. Når dette skjer, opprettes et unntaksobjekt i minnet, programmets hovedflyt avbrytes, og JVMs unntaksbehandler prøver å håndtere unntaket.

Avvikshåndtering

I Java lager vi kodeblokker der vi forventer behovet for unntakshåndtering ved å bruke try{}catch , try{}catch{}finally og try{}finally{}- konstruksjonene. Unntak i Java - 4Når et unntak blir kastet i en prøveblokk , ser JVM etter en passende unntaksbehandler i neste catch- blokk. Hvis en catch- blokk har den nødvendige unntaksbehandleren, overføres kontrollen til den. Hvis ikke, ser JVM lenger ned i kjeden av fangblokker til den riktige behandleren er funnet. Etter å ha utført en fangblokk , overføres kontrollen til den valgfrie endelige blokken. Hvis en passende fangstblokken ikke ble funnet, så stopper JVM programmet og viser stabelsporingen ( den gjeldende stabelen med metodekall), etter først å ha utført den endelige blokkeringen hvis den eksisterer. Eksempel på unntakshåndtering:

public class Print {

     void print(String s) {
        if (s == null) {
            throw new NullPointerException("Exception: s is null!");
        }
        System.out.println("Inside print method: " + s);
    }

    public static void main(String[] args) {
        Print print = new Print();
        List list= Arrays.asList("first step", null, "second step");

        for (String s : list) {
            try {
                print.print(s);
            }
            catch (NullPointerException e) {
                System.out.println(e.getMessage());
                System.out.println("Exception handled. The program will continue");
            }
            finally {
                System.out.println("Inside finally block");
            }
            System.out.println("The program is running...");
            System.out.println("-----------------");
        }

    }
    }
Her er resultatene av hovedmetoden :

Inside print method: first step
Inside finally block
The program is running...
-----------------
Exception: s is null!
Exception handled. The program will continue
Inside finally block
The program is running...
-----------------
Inside print method: second step
Inside finally block
The program is running...
-----------------
Den endelige brukes vanligvis til å lukke eventuelle strømmer og frigjøre alle ressurser som åpnes/tildeles i en prøveblokk . Men når du skriver et program, er det ikke alltid mulig å holde styr på stengingen av alle ressurser. For å gjøre livene våre enklere tilbyr Javas utviklere konstruksjonen prøv-med-ressurser , som automatisk lukker alle ressurser som åpnes i en prøveblokk . Vårt første eksempel kan skrives om med prøv-med-ressurser :

public String input() throws MyException {
    String s = null;
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))){
        s = reader.readLine();
   } catch (IOException e) {
       System.out.println(e.getMessage());
   }
    if (s.equals("")) {
        throw new MyException ("The string cannot be empty!");
    }
    return s;
}
Takket være Java-funksjoner introdusert i versjon 7, kan vi også kombinere å fange heterogene unntak i én blokk, noe som gjør koden mer kompakt og lesbar. Eksempel:

public String input() {
    String s = null;
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
        s = reader.readLine();
        if (s.equals("")) {
            throw new MyException("The string cannot be empty!");
        }
    } catch (IOException | MyException e) {
        System.out.println(e.getMessage());
    }
    return s;
}

Bunnlinjen

Ved å bruke unntak i Java kan du gjøre programmene dine mer robuste ved å lage "backup-ruter", bruke catch-blokker for å skille hovedkoden fra unntakshåndteringskoden, og bruke kast for å flytte ansvaret for unntakshåndtering til den som bruker metoden din .
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION