Le eccezioni in Java
Quando si verifica una situazione anomala in un programma Java (se questa non è gestita), la JVM
interrompe
l'esecuzione del programma stesso e crea una eccezione.
L'eccezione altro non è che un oggetto che permette di ottenere
informazioni quali:
-
il tipo di anomalia che si è verificata.
Questa informazione è ricavabile dal tipo (classe) dell'oggetto eccezione generato.
Ogni eccezione è infatti un oggetto del tipo di una classe che deriva, direttamente o indirettamente, dalla classe Throwable - un messaggio descrittivo dell'anomalia avvenuta. Per recuperare tale messaggio, le eccezioni dispongono di un apposito metodo, chiamato getMessage
- lo stack trace, ossia una rappresentazione testuale del call stack, cioè della sequenza di funzioni chiamate ed in esecuzione a partire dal main, fino alla funzione in cui è avvenuta l'anomalia
Facciamo un esempio per capire meglio i concetti.
Supponiamo di avere il seguente programma in Java che chiede all'utente di inserire due
numeri interi e calcola il quoziente della divisione.
import java.util.Scanner;
public class CalcoloQuoziente {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.print("Inserisci il dividendo: ");
int dividendo = sc.nextInt();
System.out.print("Inserisci il divisore: ");
int divisore = sc.nextInt();
int quoziente = quoziente(dividendo, divisore);
System.out.println("Il quoziente della divisione tra " + dividendo +
" e " + divisore + " è " + quoziente);
}
public static int quoziente(int dividendo, int divisore) {
return dividendo / divisore;
}
}
Se l'utente inserisce come dividendo il valore 10 e come divisore il valore 3, l'esecuzione del programma apparirà come evidenziato di seguito.
Inserisci il divisore: 3
Il quoziente della divisione tra 10 e 3 è 3
Se invece l'utente inserisse come dividendo 10 e come divisore 0, l'output dell'esecuzione del programma sarebbe il seguente.
Inserisci il divisore: 0
Exception in thread "main" java.lang.ArithmeticException: / by zero
at CalcoloQuoziente.quoziente(CalcoloQuoziente.java:21)
at CalcoloQuoziente.main(CalcoloQuoziente.java:14)
Analizziamo nel dettaglio che cosa è avvenuto.
La JVM ha provato ad eseguire la funzione che calcola la divisione tra i due valori inseriti ma,
per ovvie e note ragioni, non è stata in grado di calcolare la divisione tra 10 e 0.
Di conseguenza, ha generato una eccezione e ne ha stampato le informazioni precedentemente
elencate.
Analizziamole una ad una.
Nella prima riga troviamo il tipo di anomalia che si è
verificata.
ArithmeticException sta ad indicare che è avvenuta una anomalia
eseguendo un calcolo aritmetico.
Sempre nella prima riga troviamo la descrizione, / by zero, che
sta ad indicare che è stato
chiesto di calcolare una divisione (/) per zero.
Le due righe successive costituiscono lo stack trace, ossia la
descrizione della sequenza di chiamate di funzioni avvenute partendo dal main, fino al momento
in cui si è presentata l'anomalia.
Infatti, l'esecuzione del nostro programma è iniziata dal metodo main che, alla riga 14, ha
invocato la funzione quoziente che, a sua volta, alla riga 21, ha
eseguito l'istruzione di
divisione che è fallita in quanto il divisore era nullo.
Le chiamate delle funzioni avvenute sono indicate a partire dalla funzione in cui è avvenuta
l'anomalia e procedendo a ritroso in tutte le funzioni coinvolte, fino a giungere alla funzione
main, dalla quale è iniziata l'esecuzione del programma.
Questa caratteristica, di indicare le informazioni dalla più recente
alla meno recente, è tipica
delle strutture stack o pila, che
analizzeremo più nel dettaglio quando tratteremo le strutture dati complesse.