Forskellen mellem kaste og kaste i Java

1. Introduktion

I denne tutorial tager vi et kig på kaste og kaster i Java. Vi forklarer, hvornår vi skal bruge hver af dem.

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

2. Kaste og Kaster

Lad os starte med en hurtig introduktion. Disse nøgleord er relateret til undtagelseshåndtering. Undtagelser hæves, når strømmen til vores ansøgning forstyrres.

Der kan være mange grunde. En bruger kunne sende de forkerte inputdata. Vi kan miste en forbindelse, eller der kan opstå en anden uventet situation. Håndtering af gode undtagelser er en nøgle til at holde vores applikation i funktion efter at have set de ubehagelige øjeblikke.

Vi bruger kaste nøgleord til 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 Kan kastes. Det kan også være en Kan kastes sig selv. Vi kan ikke kaste flere undtagelser med en enkelt kaste.

Kaster nøgleord kan placeres i metodedeklarationen. Det angiver, hvilke undtagelser der kan kastes fra denne metode. Vi skal håndtere disse undtagelser med prøvefangst.

Disse to nøgleord kan ikke udskiftes!

3. Kaste i Java

Lad os se på et grundlæggende eksempel med 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 dette blev vi bedt om at implementere denne funktion:

offentlig dobbelt opdeling (dobbelt a, dobbelt b) {returnere a / b; }

Fordi vi ikke kan dele 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 øjeblik at hæve en undtagelse.

Lad os gøre det:

offentlig dobbelt opdeling (dobbelt a, dobbelt b) {hvis (b == 0) {kast nyt ArithmeticException ("Divider kan ikke være lig med nul!"); } returnere a / b; }

Som du kan se, har vi brugt Aritmetisk undtagelse passer perfekt til vores behov. Vi kan passere en enkelt Snor konstruktørparameter, som er undtagelsesmeddelelse.

3.1. God praksis

Vi foretrækker altid den mest specifikke undtagelse. Vi er nødt til at 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 et uspecifikt Undtagelse.

For eksempel er der en Heltal klasse i java.lang pakke. Lad os se på en af ​​fabriksmetodedeklarationen:

public static Integer valueOf (String s) kaster NumberFormatException 

Det er en statisk fabriksmetode, der skaber Heltal eksempel fra Snor. I tilfælde af forkert input Snor, metoden vil kaste NumberFormatException.

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

Lad os tage et kig på prøveimplementering:

offentlig klasse DivideByZeroException udvider 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:

offentlig klasse DataAcessException udvider RuntimeException {public DataAcessException (streng besked, kastbar årsag) {super (besked, årsag); }}

Konstruktøren tager to parametre: undtagelsesmeddelelse og en årsag, der kan være enhver underklasse af Kan kastes.

Lad os skrive en falsk implementering til findAll () fungere:

public List findAll () kaster SQLException {throw new SQLException (); }

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

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

Vi kaster igen SQLException indpakket i vores egen undtagelse kaldet DataAccessException. Alt bekræftes ved følgende test:

@Test ugyldigt nårSQLExceptionIsThrown_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 enhver mulig undtagelse i systemet.

Også komponenter på højere niveau behøver ikke at vide om komponenter på bundniveau eller de undtagelser, de kaster.

3.3. Multi-Catch med Java

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

Lad os se på en mere omfattende prøvefangerblok:

prøv {tryCatch.execute (); } fange (ConnectionException | SocketException ex) {System.out.println ("IOException"); } fange (Undtagelse ex) {System.out.println ("Generel undtagelse"); }

Det udføre metoden kan kaste tre undtagelser: SocketException, ConnectionException, Undtagelse. Den første fangstblok fanges ConnectionException eller SocketException. Den anden fangstblok ville fange Undtagelse eller enhver anden underklasse af Undtagelse. Huske på, at vi skal altid fange en mere detaljeret undtagelse først.

Vi kan bytte rækkefølgen af ​​vores fangstblokke. Derefter ville vi aldrig fange SocketException og ConnectionException fordi alt går i fangsten med Undtagelse.

4. Kaster i Java

Vi tilføjer kaster til metodedeklarationen.

Lad os se på en af ​​vores tidligere metodedeklarationer:

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

Metoden kan kaste flere undtagelser. De adskilles med kommaer i slutningen af ​​en metodedeklaration. Vi kan sætte begge, afkrydsede og ikke-markerede undtagelser i kaster. Vi har beskrevet forskellen mellem dem nedenfor.

4.1. Kontrollerede 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 hjælp af kaster nøgleord.

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

Der er et kort eksempel:

Filfil = ny fil ("not_existing_file.txt"); prøv {FileInputStream stream = ny FileInputStream (fil); } fange (FileNotFoundException e) {e.printStackTrace (); }

Vi kan undgå at bruge prøvefangstblok ved at tilføje kaster til metodedeklarationen:

privat statisk ugyldigt uncheckedException () kaster FileNotFoundException {File file = new File ("not_existing_file.txt"); FileInputStream stream = ny FileInputStream (fil); }

Desværre skal en funktion på et højere niveau stadig håndtere denne undtagelse. Ellers er vi nødt til at sætte denne undtagelse i metodedeklaration med kaster nøgleord.

Som det modsatte, ikke-markerede undtagelser kontrolleres ikke på kompileringstidspunktet.

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

Ikke-markerede undtagelser kastes under kørselstid. Den følgende kode kaster en NullPointerException. Det er sandsynligvis en af ​​de mest almindelige undtagelser i Java.

At kalde en metode på en null-reference vil resultere i denne undtagelse:

offentlig ugyldig runtimeNullPointerException () {String a = null; a. længde (); }

Lad os kontrollere denne adfærd i testen:

@Test ugyldigt nårCalled_thenNullPointerExceptionIsThrown () {assertThrows (NullPointerException.class, () -> simpleService.runtimeNullPointerException ()); }

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

I Java, hver underklasse af Fejl og RuntimeException er en ukontrolleret undtagelse. En kontrolleret undtagelse er alt andet under Kan kastes klasse.

5. Konklusion

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

Som altid kan kildekoden findes på vores GitHub.

Hvis du vil gå dybere ind i håndtering af undtagelser i Java, skal du se vores artikel om Java-undtagelser.