ProgrammazioneSviluppatore Backend

Quali sono le differenze tra eccezioni checked e unchecked in Java, come progettare correttamente la gestione degli errori e quali errori evitare quando le si utilizzano?

Supera i colloqui con l'assistente IA Hintsage

Risposta

In Java le eccezioni sono suddivise in checked (verificate) e unchecked (non verificate).

  • Checked exceptions — ereditano da Exception, ma non da RuntimeException. Il compilatore richiede esplicitamente di gestirle con try-catch oppure di dichiararle in throws.
  • Unchecked exceptions — ereditano da RuntimeException. Il compilatore non richiede la loro gestione obbligatoria.
public void readFile(String file) throws IOException { /* ... */ } // checked public void divide(int a, int b) { int res = a/b; } // unchecked (ArithmeticException)

La principale sottigliezza è che le checked exceptions vengono utilizzate per situazioni attese e recuperabili (ad esempio, errori di input-output), mentre le unchecked vengono utilizzate per errori di logica e situazioni critiche da cui non è possibile recuperare (ad esempio, NullPointerException).

Domanda trabocchetto

Domanda: È necessario gestire o dichiarare in throws un'eccezione unchecked, se il tuo metodo può lanciarla?

Risposta: No. Il compilatore non richiede di controllare o dichiarare eccezioni non recuperabili (unchecked). La loro gestione è a tua discrezione; puoi utilizzare try-catch, ma più spesso — lasciare che "cada" fino al gestore globale.

public void foo() { throw new IllegalArgumentException(); } // Non richiede gestione o dichiarazione

Esempi di errori reali a causa dell'ignoranza delle sottigliezze del tema


Storia

Nel progetto dell'API bancaria, durante la gestione degli errori di input-output venivano lanciati RuntimeException invece di checked. Di conseguenza, i clienti non erano obbligati a gestirli, il che portava a un funzionamento scorretto in caso di perdita di connessione con il server, e l'applicazione "cadeva" senza informare l'utente.


Storia

Uno sviluppatore ha dichiarato un numero eccessivo di throws Exception nelle firme dei metodi (ad esempio, del database), il che ha costretto tutti i metodi utilizzati sopra a dover utilizzare try-catch o a dichiarare anche loro throws. Questo ha sporcato il codice, ha peggiorato la leggibilità e ha reso difficile il refactoring.


Storia

In uno dei microservizi venivano catturate tutte le eccezioni con un generico catch (Exception e). Questo catturava anche le eccezioni unchecked (ad esempio, NullPointerException), il che portava a una "silenziosa" ignoranza di errori critici — il servizio lavorava con dati non corretti.