Ce face try, catch și finally
Când apare o problemă (împărțire la zero, text care nu e număr, fișier lipsă), Java aruncă o excepție: un obiect care descrie eroarea. Dacă nimeni nu o prinde, programul se oprește și afișează stiva de apeluri. Codul pus în try este „supravegheat”: la prima excepție, restul blocului este sărit și se execută primul catch al cărui tip se potrivește.
Poți avea mai multe catch-uri, de la tipul cel mai specific la cel mai general, sau un singur catch cu mai multe tipuri separate prin |. Obiectul excepției (e) are getMessage() și getClass(); e.printStackTrace() afișează detaliile complete.
Blocul finally rulează mereu: după try fără erori, după un catch, chiar și când try face return sau aruncă mai departe. Este locul pentru eliberarea resurselor, deși pentru fișiere și conexiuni try-with-resources este mai simplu.
Exemple
Exemplul 1: Prinderea erorilor de conversie
Fiecare text este convertit separat. Unde conversia eșuează, se execută catch, iar bucla continuă cu următorul.
public class Main {
public static void main(String[] args) {
String[] intrari = {"42", "3.5", "abc", "-7", ""};
int suma = 0;
for (String text : intrari) {
try {
int n = Integer.parseInt(text);
suma += n;
System.out.println("OK: " + n);
} catch (NumberFormatException e) {
System.out.println("Ignor \"" + text + "\": " + e.getMessage());
}
}
System.out.println("Suma: " + suma);
}
}
Rezultat
OK: 42
Ignor "3.5": For input string: "3.5"
Ignor "abc": For input string: "abc"
OK: -7
Ignor "": For input string: ""
Suma: 35
Exemplul 2: Mai multe catch-uri și multi-catch
Fiecare caz aruncă alt tip de excepție. ArithmeticException are blocul ei; celelalte două sunt prinse împreună cu |.
public class Main {
static int imparte(String[] date, int index, int impartitor) {
int valoare = Integer.parseInt(date[index]);
return valoare / impartitor;
}
public static void main(String[] args) {
String[] date = {"100", "x", "60"};
int[][] cazuri = {{0, 4}, {0, 0}, {1, 2}, {5, 1}};
for (int[] c : cazuri) {
try {
System.out.println("rezultat: " + imparte(date, c[0], c[1]));
} catch (ArithmeticException e) {
System.out.println("împărțire la zero");
} catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
System.out.println(e.getClass().getSimpleName() + ": " + e.getMessage());
}
}
}
}
Rezultat
rezultat: 25
împărțire la zero
NumberFormatException: For input string: "x"
ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 3
Exemplul 3: finally rulează mereu
Chiar și când try face return sau când apare o excepție, mesajul din finally se afișează. Ordinea afișării arată exact când rulează fiecare bloc.
public class Main {
static String citesteNota(String text) {
System.out.println(" deschid catalogul");
try {
int nota = Integer.parseInt(text);
return "nota " + nota;
} catch (NumberFormatException e) {
return "notă invalidă";
} finally {
System.out.println(" închid catalogul");
}
}
public static void main(String[] args) {
System.out.println(citesteNota("9"));
System.out.println(citesteNota("nouă"));
}
}
Rezultat
deschid catalogul
închid catalogul
nota 9
deschid catalogul
închid catalogul
notă invalidă
Greșeli frecvente
- Prinzi
Exceptionși nu faci nimic (catch (Exception e) { }). Eroarea dispare fără urmă și bug-ul devine foarte greu de găsit. Prinde tipul exact și măcar afișează sau loghează mesajul. - Pui
catch (Exception e)înaintea unuicatch (NumberFormatException e):exception NumberFormatException has already been caught. Ordinea este de la specific la general. - Faci
returndinfinally: înlocuiește valoarea sau excepția dintry, iar-Xlintavertizează ([finally] finally clause cannot complete normally).
Comenzi înrudite
throw și throws: throw aruncă o excepție acum; throws, în antetul metodei, anunță ce excepții verificate poate arunca metoda.Excepții verificate și neverificate: Excepțiile verificate (Exception) trebuie prinse sau declarate cu throws; cele neverificate (RuntimeException) nu sunt cerute de compilator.try-with-resources: try-with-resources deschide resurse (fișiere, conexiuni) în paranteze și le închide automat la final, chiar dacă apare o excepție.Exception: Clasa de bază pentru erorile pe care un program le poate trata; getMessage() returnează mesajul dat la creare.NumberFormatException: Apare când un text nu poate fi transformat în număr: Integer.parseInt(„12a”), „3,14” cu virgulă, text gol.