Sostieni AppuntiFacili con una piccola donazione su PayPal
Dona con PayPalLe eccezioni sono il meccanismo di Java per gestire situazioni impreviste a runtime: un file non trovato, una divisione per zero, un indice fuori range…
Senza gestione degli errori il programma si interrompe bruscamente (crash). Con try/catch possiamo intercettare il problema e reagire in modo controllato.
In Java le eccezioni sono oggetti — istanze di classi che estendono Throwable.
graph BT
subgraph Gerarchia Eccezioni
Throwable --> Object
Exception --> Throwable
RuntimeException --> Exception
Fallimento --> Exception
IOException --> Exception
NullPointerException --> RuntimeException
DenominatoreNullo --> RuntimeException
NumberFormatException --> RuntimeException
end
note1["Nota: def. da utente"]
note1 -.- DenominatoreNullo & Fallimento
note2["Nota: di libreria"]
note2 -.- IOException & NullPointerException & NumberFormatException
style note1 stroke-width:2px,color:#0057e7
style note2 stroke-width:2px,color:#0057e7
throws. Es: IOException.RuntimeException, non sono obbligatorie. Es: NullPointerException, ArithmeticException.try {
// codice che potrebbe lanciare un'eccezione
} catch (TipoEccezione e) {
// cosa fare se l'eccezione si verifica
} finally {
// eseguito SEMPRE, con o senza eccezione
}
public class Main {
public static void main(String[] args) {
int a = 10;
int b = 0;
try {
int risultato = a / b;
System.out.println("Risultato: " + risultato);
} catch (ArithmeticException e) {
System.out.println("Errore: non puoi dividere per zero!");
}
}
}
Output:
Errore: non puoi dividere per zero!
public class Main {
public static void main(String[] args) {
String testo = null;
try {
System.out.println(testo.length());
} catch (NullPointerException e) {
System.out.println("Errore: accesso a un riferimento nullo!");
}
}
}
Si possono gestire più tipi di eccezione:
try {
// operazioni rischiose
} catch (NullPointerException e) {
System.out.println("Oggetto nullo!");
} catch (ArithmeticException e) {
System.out.println("Errore matematico!");
} catch (Exception e) {
// cattura qualsiasi altra eccezione
System.out.println("Errore generico: " + e.getMessage());
}
catch (Exception e) va sempre per ultimo — è il più generico.
try {
System.out.println("Apro il file...");
// lettura file
} catch (Exception e) {
System.out.println("Errore durante la lettura.");
} finally {
System.out.println("Chiudo le risorse."); // eseguito sempre
}
Usato tipicamente per chiudere file, connessioni, scanner.
Puoi lanciare un’eccezione manualmente:
public static void controllaEta(int eta) {
if (eta < 0) {
throw new IllegalArgumentException("L'età non può essere negativa!");
}
System.out.println("Età valida: " + eta);
}
public class Main {
public static void main(String[] args) {
try {
controllaEta(-5);
} catch (IllegalArgumentException e) {
System.out.println("Errore: " + e.getMessage());
}
}
}
Java permette di definire eccezioni proprie estendendo RuntimeException (unchecked) o Exception (checked).
class DenominatoreNulloException extends RuntimeException {
public DenominatoreNulloException(String message) {
super(message);
}
}
public class Main {
public static void main(String[] args) {
try {
System.out.println(divide(10, 0));
} catch (DenominatoreNulloException e) {
System.out.println(e.getMessage());
}
}
public static int divide(int numeratore, int denominatore) {
if (denominatore == 0) {
throw new DenominatoreNulloException("Denominatore uguale a 0!");
}
return numeratore / denominatore;
}
}
Ogni eccezione porta informazioni sull’errore:
} catch (Exception e) {
System.out.println(e.getMessage()); // messaggio breve
e.printStackTrace(); // intera catena di chiamate
}
printStackTrace() produce output come:
java.lang.ArithmeticException: / by zero
at Main.main(Main.java:8)
Quando il programma crasha, Java stampa una stack trace. Saperla leggere è essenziale per il debug.
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "str" is null
at com.esempio.Main.stampaLunghezza(Main.java:12) ← riga del TUO codice
at com.esempio.Main.main(Main.java:6) ← dove è stato chiamato
Come leggerla:
at → classe e riga dove si è verificato il problemaRegola pratica: la prima riga at con il tuo package è la riga da correggere.
| Eccezione | Causa tipica |
|---|---|
NullPointerException | Usare un oggetto null |
ArrayIndexOutOfBoundsException | Indice fuori dal range dell’array |
NumberFormatException | Convertire una stringa non numerica |
ArithmeticException | Divisione per zero |
ClassCastException | Cast non valido tra tipi |
IOException | Errore su file o rete |
StackOverflowError | Ricorsione infinita |
import java.io.FileReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
FileReader file = new FileReader("dati.txt");
// lettura file...
} catch (IOException e) {
System.out.println("File non trovato: " + e.getMessage());
}
}
}
IOException è checked: il compilatore obbliga a gestirla.
Cosa fa il blocco catch?
Quale blocco viene eseguito SEMPRE, con o senza eccezione?
Quale metodo stampa l'intera stack trace?
Quale eccezione si verifica dividendo per zero?
Qual è la differenza tra checked e unchecked exception?
Gestione delle eccezioni in linguaggio Java: esercizi risolti
Scrivi un metodo dividi(int a, int b) che gestisce la divisione per zero.
public class Main {
public static int dividi(int a, int b) {
try {
return a / b;
} catch (ArithmeticException e) {
System.out.println("Impossibile dividere per zero!");
return 0;
}
}
public static void main(String[] args) {
System.out.println(dividi(10, 2)); // -> 5
System.out.println(dividi(10, 0)); // -> messaggio + 0
}
}Chiedi all’utente un numero con Scanner, gestisci il caso in cui inserisca una stringa.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Inserisci un numero: ");
try {
int numero = Integer.parseInt(input.nextLine());
System.out.println("Numero inserito: " + numero);
} catch (NumberFormatException e) {
System.out.println("Errore: non è un numero valido!");
} finally {
input.close();
}
}
}Crea un’eccezione EtaNonValidaException e usala in un metodo che verifica che l’età sia tra 0 e 120.
class EtaNonValidaException extends RuntimeException {
public EtaNonValidaException(String message) {
super(message);
}
}
public class Main {
public static void verificaEta(int eta) {
if (eta < 0 || eta > 120) {
throw new EtaNonValidaException("Età non valida: " + eta);
}
System.out.println("Età accettata: " + eta);
}
public static void main(String[] args) {
try {
verificaEta(25);
verificaEta(150);
} catch (EtaNonValidaException e) {
System.out.println("Errore: " + e.getMessage());
}
}
}