Java >> Java tutorial >  >> Tag >> throw

Forskellen mellem kast og kast i Java

1. Introduktion

I dette selvstudie tager vi et kig på det kast og kast i Java. Vi forklarer, hvornår vi skal bruge hver af dem.

Dernæst viser vi nogle eksempler på deres grundlæggende brug.

2. Smid og kast

Lad os starte med en hurtig introduktion. Disse nøgleord er relateret til håndtering af undtagelser. Undtagelser er rejst, når det normale flow i vores applikation er forstyrret.

Der kan være mange årsager. En bruger kan sende de forkerte inputdata. Vi kan miste en forbindelse, eller der kan opstå en anden uventet situation. God håndtering af undtagelser er en nøgle til at holde vores applikation i gang efter en optræden af ​​disse ubehagelige øjeblikke.

Vi bruger throw søgeord for eksplicit at kaste en undtagelse fra koden. Det kan være en hvilken som helst metode eller statisk blok. Denne undtagelse skal være en underklasse af Throwable. Det kan også være en kastbar sig selv. Vi kan ikke kaste flere undtagelser med et enkelt kast .

Skast nøgleord kan placeres i metodedeklarationen. Det angiver, hvilke undtagelser der kan kastes fra denne metode. Vi skal håndtere disse undtagelser med try-catch.

Disse to søgeord kan ikke udskiftes!

3. Smid i Java

Lad os tage et kig på et grundlæggende eksempel med at kaste en undtagelse fra metoden.

Forestil dig først og fremmest, at vi skriver en simpel lommeregner. En af de grundlæggende aritmetiske operationer er division. På grund af det blev vi bedt om at implementere denne funktion:

public double divide(double a, double b) {
    return a / b;
}

Fordi vi ikke kan dividere med nul, er vi nødt til at tilføje nogle ændringer til vores eksisterende kode. Det ser ud til, at det er et godt tidspunkt til at rejse en undtagelse.

Lad os gøre dette:

public double divide(double a, double b) {
    if (b == 0) {
        throw new ArithmeticException("Divider cannot be equal to zero!");
    }
    return a / b;
}

Som du kan se, har vi brugt ArithmeticException med passer perfekt til vores behov. Vi kan sende en enkelt streng konstruktørparameter, som er undtagelsesmeddelelse.

3.1. God praksis

Vi bør altid foretrække den mest specifikke undtagelse. Vi skal finde en klasse, der passer bedst til vores ekstraordinære begivenhed. Kast f.eks. NumberFormatException  i stedet for IllegalArgumentException. Vi bør undgå at smide en uspecifik undtagelse .

For eksempel er der et heltal klasse i java.lang pakke. Lad os tage et kig på en af ​​fabriksmetodeerklæringen:

public static Integer valueOf(String s) throws NumberFormatException

Det er en statisk fabriksmetode, som skaber Heltal instans fra String. I tilfælde af forkert input String , vil metoden kaste NumberFormatException.

En god idé er at definere vores egen, mere beskrivende undtagelse. I vores Lommeregner  klasse, der for eksempel kunne være DivideByZeroException.

Lad os tage et kig på eksempelimplementering:

public class DivideByZeroException extends RuntimeException {

    public DivideByZeroException(String message) {
        super(message);
    }
}

3.2. Indpakning af en eksisterende undtagelse

Nogle gange ønsker vi at pakke en eksisterende undtagelse ind i den undtagelse, der er defineret af os.

Lad os starte med at definere vores egen undtagelse:

public class DataAcessException extends RuntimeException {
    
    public DataAcessException(String message, Throwable cause) {
        super(message, cause);
    }
}

Konstruktøren tager to parametre:undtagelsesmeddelelse og en årsag, som kan være en hvilken som helst underklasse af Throwable.

Lad os skrive en falsk implementering for findAll()  funktion:

public List<String> findAll() throws SQLException {
    throw new SQLException();
}

Nu i SimpleService lad os kalde en lagerfunktion, som kan resultere i SQLException:

public void wrappingException() {
    try {
        personRepository.findAll();
    } catch (SQLException e) {
        throw new DataAccessException("SQL Exception", e);
    }
}

Vi genudsender SQLException pakket ind i vores egen undtagelse kaldet DataAccessException. Alt er verificeret ved følgende test:

@Test
void whenSQLExceptionIsThrown_thenShouldBeRethrownWithWrappedException() {
    assertThrows(DataAccessException.class,
      () -> simpleService.wrappingException());
}

Der er to grunde til at gøre dette. Først og fremmest bruger vi undtagelsesindpakning, fordi resten af ​​koden ikke behøver at vide om alle mulige undtagelser i systemet.

Komponenter på højere niveau behøver heller ikke at kende til komponenter på nederste niveau, eller de undtagelser, de giver.

3.3. Multi-Catch med Java

Nogle gange kan de metoder, vi bruger, give mange forskellige undtagelser.

Lad os tage et kig på en mere omfattende try-catch blok:

try {
    tryCatch.execute();
} catch (ConnectionException | SocketException ex) {
    System.out.println("IOException");
} catch (Exception ex) {
    System.out.println("General exception");
}

udfør metode kan give tre undtagelser: SocketException, ConnectionException, Exception. Den første catch-blok fanger ConnectionException eller SocketException . Den anden catch-blok ville fange undtagelse  eller enhver anden underklasse af undtagelse. Husk, at vi bør altid fange en mere detaljeret undtagelse først.

Vi kan bytte rækkefølgen på vores fangblokke. Så ville vi aldrig fange SocketException og ConnectionException fordi alt vil gå til fange med Undtagelse .

4. Skast i Java

Vi tilføjer kast  til metodedeklarationen.

Lad os tage et kig på en af ​​vores tidligere metodeerklæringer:

public static void execute() throws SocketException, ConnectionException, Exception

Metoden kan give flere undtagelser. De er kommasepareret i slutningen af ​​en metodeerklæring. Vi kan indsætte både markerede og umarkerede undtagelser i kastene. Vi har beskrevet forskellen mellem dem nedenfor.

4.1. Markerede og ikke-markerede undtagelser

En markeret undtagelse betyder, at den er markeret på kompileringstidspunktet. Bemærk, at vi skal håndtere denne undtagelse. Ellers skal en metode angive en undtagelse ved at bruge kast søgeord.

De mest almindelige kontrollerede undtagelser er IOException, FileNotFoundException, ParseException. FileNotFoundException  kan blive kastet, når vi opretter FileInputStream  fra Fil.

Der er et kort eksempel:

File file = new File("not_existing_file.txt");
try {
    FileInputStream stream = new FileInputStream(file);
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

Vi kan undgå at bruge try-catch-blok ved at tilføje kast  til metodedeklarationen:

private static void uncheckedException() throws FileNotFoundException {
    File file = new File("not_existing_file.txt");
    FileInputStream stream = new FileInputStream(file);
}

Desværre skal en funktion på højere niveau stadig håndtere denne undtagelse. Ellers er vi nødt til at sætte denne undtagelse i metodeerklæring med throws keyword.

Modsat er umarkerede undtagelser ikke markeret på kompileringstidspunktet.

De mest almindelige umarkerede undtagelser er: ArrayIndexOutOfBoundsException, IllegalArgumentException, NullPointerException.

Umarkerede undtagelser kommer under kørsel. Følgende kode vil kaste en NullPointerException. Det er sandsynligvis en af ​​de mest almindelige undtagelser i Java.

Kaldning af en metode på en nul-reference vil resultere i denne undtagelse:

public void runtimeNullPointerException() {
    String a = null;
    a.length();
}

Lad os verificere denne adfærd i testen:

@Test
void whenCalled_thenNullPointerExceptionIsThrown() {
    assertThrows(NullPointerException.class,
      () -> simpleService.runtimeNullPointerException());
}

Husk, at denne kode og test ikke giver meget mening. Det er kun til læringsformål at forklare runtime undtagelser.

I Java, hver underklasse af Fejl og RuntimeException er en ukontrolleret undtagelse. En markeret undtagelse er alt andet under Smidbar klasse.

5. Konklusion

I denne artikel har vi diskuteret forskellen mellem to Java-nøgleord:kast og kast. Vi har gennemgået den grundlæggende brug og talt lidt om god praksis. Så har vi talt om kontrollerede og umarkerede undtagelser.

Som altid kan kildekoden findes på vores GitHub.

Hvis du vil gå dybere ind i håndtering af undtagelser i Java, så tag et kig på vores artikel om Java-undtagelser.


Java tag