CodeGym /Java Course /Modulo 1 /Tipi di eccezioni

Tipi di eccezioni

Modulo 1
Livello 21 , Lezione 3
Disponibile

1. Tipi di eccezioni

Tutte le eccezioni sono divise in 4 tipi, che in realtà sono classi che si ereditano a vicenda.

Throwableclasse

La classe base per tutte le eccezioni è la Throwableclasse. La Throwableclasse contiene il codice che scrive lo stack di chiamate corrente (traccia dello stack del metodo corrente) in un array. Impareremo cos'è una traccia dello stack un po' più tardi.

L' operatore throw può accettare solo un oggetto che deriva dalla Throwableclasse. E sebbene tu possa teoricamente scrivere codice come throw new Throwable();, di solito nessuno lo fa. Lo scopo principale della Throwableclasse è avere un'unica classe genitore per tutte le eccezioni.

Errorclasse

La prossima classe di eccezione è la Errorclasse, che eredita direttamente la Throwableclasse. La macchina Java crea oggetti della Errorclasse (e dei suoi discendenti) quando si sono verificati problemi seri . Ad esempio, un malfunzionamento dell'hardware, memoria insufficiente, ecc.

Di solito, come programmatore, non c'è niente che tu possa fare in una situazione in cui si è verificato un tale errore (il tipo per il quale Errordovrebbe essere lanciato un an): questi errori sono troppo gravi. Tutto quello che puoi fare è notificare all'utente che il programma si sta arrestando in modo anomalo e/o scrivere tutte le informazioni note sull'errore nel registro del programma.

Exceptionclasse

Le classi Exceptione RuntimeExceptionsono per errori comuni che si verificano nel funzionamento di molti metodi. L'obiettivo di ogni eccezione generata è essere catturato da un catchblocco che sappia come gestirlo correttamente.

Quando un metodo non può completare il proprio lavoro per qualche motivo, dovrebbe immediatamente avvisare il metodo chiamante generando un'eccezione del tipo appropriato.

In altre parole, se una variabile è uguale a null, il metodo genererà un NullPointerException. Se gli argomenti errati sono stati passati al metodo, genererà un file InvalidArgumentException. Se il metodo divide accidentalmente per zero, genererà un'estensione ArithmeticException.

RuntimeExceptionclasse

RuntimeExceptionssono un sottoinsieme di Exceptions. Potremmo anche dire che RuntimeExceptionè una versione leggera delle eccezioni ordinarie ( Exception) — meno requisiti e restrizioni sono imposti a tali eccezioni

Imparerai la differenza tra Exceptione RuntimeExceptiondopo.


2. Throws: eccezioni verificate

Tutte le eccezioni Java rientrano in 2 categorie: verificate e non verificate .

Tutte le eccezioni che ereditano RuntimeExceptiono Errorsono considerate eccezioni non controllate . Tutte le altre sono eccezioni controllate .

Importante!

Vent'anni dopo l'introduzione delle eccezioni verificate, quasi tutti i programmatori Java lo considerano un bug. Nei framework moderni più diffusi, il 95% di tutte le eccezioni è deselezionato. Il linguaggio C#, che quasi copiava esattamente Java, non aggiungeva eccezioni controllate .

Qual è la differenza principale tra eccezioni controllate e non controllate ?

Ci sono ulteriori requisiti imposti sulle eccezioni verificate . In parole povere sono questi:

Requisito 1

Se un metodo genera un'eccezione verificata , deve indicare il tipo di eccezione nella sua firma . In questo modo, ogni metodo che lo chiama è consapevole che questa "eccezione significativa" potrebbe verificarsi in esso.

Indica le eccezioni verificate dopo i parametri del metodo dopo la throwsparola chiave (non utilizzare la throwparola chiave per errore). Assomiglia a questo:

type method (parameters) throws exception

Esempio:

eccezione verificata eccezione non verificata
public void calculate(int n) throws Exception
{
   if (n == 0)
      throw new Exception("n is null!");
}
public void calculate(n)
{
   if (n == 0)
      throw new RuntimeException("n is null!");
}

Nell'esempio a destra, il nostro codice genera un'eccezione non verificata : non è richiesta alcuna azione aggiuntiva. Nell'esempio a sinistra, il metodo genera un'eccezione verificata , quindi la throwsparola chiave viene aggiunta alla firma del metodo insieme al tipo di eccezione.

Se un metodo prevede di generare più eccezioni controllate , tutte devono essere specificate dopo la throwsparola chiave, separate da virgole. L'ordine non è importante. Esempio:

public void calculate(int n) throws Exception, IOException
{
   if (n == 0)
      throw new Exception("n is null!");
   if (n == 1)
      throw new IOException("n is 1");
}

Requisito 2

Se chiami un metodo che ha verificato le eccezioni nella sua firma, non puoi ignorare il fatto che le genera.

Devi rilevare tutte queste eccezioni aggiungendo catchblocchi per ognuna o aggiungendole a una throwsclausola per il tuo metodo.

È come se stessimo dicendo: " Queste eccezioni sono così importanti che dobbiamo rilevarle. E se non sappiamo come gestirle, allora chiunque chiami il nostro metodo deve essere avvisato che tali eccezioni possono verificarsi in esso.

Esempio:

Immagina di scrivere un metodo per creare un mondo popolato da umani. Il numero iniziale di persone viene passato come argomento. Quindi dobbiamo aggiungere eccezioni se ci sono troppo poche persone.

Creare la Terra Nota
public void createWorld(int n) throws EmptyWorldException, LonelyWorldException
{
   if (n == 0)
      throw new EmptyWorldException("There are no people!");
   if (n == 1)
      throw new LonelyWorldException ("There aren't enough people!");
   System.out.println("A wonderful world was created. Population: " + n);
}
Il metodo genera potenzialmente due eccezioni verificate :

  • EmptyWorldException
  • LonelyWorldException

Questa chiamata al metodo può essere gestita in 3 modi:

1. Non cogliere eccezioni

Questo è più spesso fatto quando il metodo non sa come gestire correttamente la situazione.

Codice Nota
public void createPopulatedWorld(int population)
throws EmptyWorldException, LonelyWorldException
{
   createWorld(population);
}
Il metodo chiamante non rileva le eccezioni e deve informarne gli altri: le aggiunge alla propria throwsclausola

2. Cattura alcune delle eccezioni

Gestiamo gli errori che possiamo gestire. Ma quelli che non capiamo, li lanciamo al metodo di chiamata. Per fare ciò, dobbiamo aggiungere il loro nome alla clausola throws:

Codice Nota
public void createNonEmptyWorld(int population)
throws EmptyWorldException
{
   try
   {
      createWorld(population);
   }
   catch (LonelyWorldException e)
   {
      e.printStackTrace();
   }
}
Il chiamante rileva solo un'eccezione verificata : LonelyWorldException. L'altra eccezione va aggiunta alla sua firma, indicandola dopo la throwsparola chiave

3. Cattura tutte le eccezioni

Se il metodo non genera eccezioni al metodo chiamante, il metodo chiamante è sempre sicuro che tutto abbia funzionato correttamente. E non sarà in grado di intraprendere alcuna azione per risolvere una situazione eccezionale.

Codice Nota
public void createAnyWorld(int population)
{
   try
   {
      createWorld(population);
   }
   catch (LonelyWorldException e)
   {
      e.printStackTrace();
   }
   catch (EmptyWorldException e)
   {
      e.printStackTrace();
   }
}
Tutte le eccezioni vengono rilevate in questo metodo. Il chiamante sarà sicuro che tutto è andato bene.


3. Cattura di più eccezioni

I programmatori odiano davvero duplicare il codice. Hanno persino escogitato un principio di sviluppo corrispondente: DRY : Don't Repeat Yourself. Ma quando si gestiscono le eccezioni, ci sono frequenti occasioni in cui un tryblocco è seguito da più catchblocchi con lo stesso codice.

Oppure potrebbero esserci 3 catchblocchi con lo stesso codice e altri 2 catchblocchi con altro codice identico. Questa è una situazione standard in cui il tuo progetto gestisce le eccezioni in modo responsabile.

A partire dalla versione 7, nel linguaggio Java è stata aggiunta la possibilità di specificare più tipi di eccezioni in un singolo catchblocco. Sembra più o meno così:

try
{
   // Code where an exception might occur
}
catch (ExceptionType1 | ExceptionType2 | ExceptionType3 name)
{
   // Exception handling code
}

Puoi avere tutti catchi blocchi che vuoi. Tuttavia, un singolo catchblocco non può specificare eccezioni che si ereditano a vicenda. In altre parole, non puoi scrivere catch ( Exception| RuntimeExceptione), perché la RuntimeExceptionclasse eredita Exception.



Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION