Ovunque andiamo, ci aspettano eventi imprevedibili. Terremoti, azioni irrazionali di persone, meteoriti... o qualcosa di più semplice: una lampadina si brucia, una carta di credito si smagnetizza, l'indicatore della benzina si rompe. Non possiamo impedire eventi imprevedibili, ma possiamo almeno essere parzialmente preparati ad affrontarli. Dobbiamo cioè predisporre alcuni meccanismi per affrontarli. Nel mondo della programmazione, in particolare nel linguaggio Java, gli eventi che impediscono il normale funzionamento di un programma sono chiamati eccezioni, mentre i meccanismi per prevenire i crash del programma sono chiamati gestione delle eccezioni. Pertanto, quando si verifica un evento inaspettato in un programma, come una divisione per zero, dovrebbe "lanciare" un'eccezione. La gestione delle eccezioni è un aspetto importante della programmazione Java che aiuta gli sviluppatori a gestire gli errori e le eccezioni che possono verificarsi durante l'esecuzione di un programma. In questo articolo ci concentreremo su uno dei concetti fondamentali della gestione delle eccezioni: la parola chiave Java Throw e come utilizzarla per generare un'eccezione.
Cos'è un'eccezione in Java?
Un'eccezione è un evento che si verifica durante l'esecuzione di un programma che interrompe il normale flusso delle istruzioni del programma. Quando si verifica un'eccezione, l'esecuzione del programma viene interrotta e il messaggio di errore viene visualizzato sulla console. In Java esistono due tipi di eccezioni: selezionate e non selezionate. Le eccezioni controllate vengono controllate in fase di compilazione e il compilatore garantisce che vengano rilevate o dichiarate dal metodo chiamante. D'altro canto, le eccezioni non controllate non vengono controllate in fase di compilazione e possono essere rilevate o lasciate non rilevate. Ecco un esempio di codice in cui potrebbe verificarsi un errore, ma il compilatore lo salta.public class Factorial {
public static long getFactorial(final int number) {
long fact = 1;
for (int i = 1; i <= number; i++) {
fact = fact * i;
}
return fact;
}
public static void main(String[] args) {
System.out.println(getFactorial(-5));
System.out.println(getFactorial(21));
}
}
Ecco l'output del programma:
1-4249290049419214848
Il programma è terminato correttamente, ma ha prodotto un risultato errato. Nel primo caso, perché l'argomento della funzione era negativo e il fattoriale non funziona con i numeri negativi. Nel secondo caso, il risultato era sbagliato, perché il numero è troppo grande per poter contare il suo fattoriale nell'intervallo di tipo lungo. Ecco un altro esempio. Scriviamo un programma in cui divideremo un numero per un altro.
public class DivisionExample {
public static void main(String[] args) {
int a = 10;
int b = 0;
int result = divide(a, b);
System.out.println(result);
}
public static int divide(int a, int b) {
return a / b;
}
}
In questo esempio, verrà lanciata un'ArithmeticException perché la variabile b è zero. Tuttavia, questo errore non viene gestito, quindi il programma esce con uno stato non corretto.
Come generare un'eccezione in Java
In Java, anche le eccezioni sono oggetti, quindi un'eccezione viene lanciata proprio come viene creato un nuovo oggetto Exception. Viene lanciata un'eccezione in un programma utilizzando l'istruzione Throw. Di solito, queste due operazioni (creazione di un oggetto e generazione di un'eccezione) sono combinate in una:throw new Exception("error…");
La parola chiave Throw in Java viene utilizzata per generare un'eccezione da un metodo o da un blocco di codice quando si verifica un errore o una condizione eccezionale che il programma non è in grado di gestire in fase di runtime. Il flusso del programma viene reindirizzato al blocco catch più vicino. Questo blocco può gestire l'eccezione.
Esempio dell'utilizzo della parola chiave "lancia".
Per illustrare la funzionalità della parola chiave Throw in Java, facciamo un esempio. Scriviamo un metodo per calcolare il fattoriale di un numero. Se il numero è negativo, non può essere calcolato, quindi è necessario lanciare un'eccezione. Allo stesso modo, se il numero è troppo grande, il risultato fattoriale supererà la dimensione massima di un tipo lungo e verrà generata un'altra eccezione. Qui abbiamo un'implementazione del metodo:public Class Factorial {
public static long getFactorial(final int number) {
if ((number >= 0) && (number < 21)) {
long fact = 1;
for (int i = 1; i <= number; i++) {
fact = fact * i;
}
return fact;
} else {
//throw new exception here
throw new IllegalArgumentException("THe argument isn't legal");
}
}
public static void main(String[] args) {
System.out.println(getFactorial(-5));
System.out.println(getFactorial(21));
}
}
In questo esempio, se il valore di number è negativo, la parola chiave Throw viene utilizzata per generare un'istanza della classe IllegalArgumentException . Se esegui il programma, sulla console verrà visualizzato il messaggio "L'argomento non è legale" . L'esecuzione del programma verrà interrotta.
Niente più errori: intercettare un esempio di eccezione
Ora ricordiamo il secondo esempio, con la divisione per zero, ed eseguiamolo con la gestione delle eccezioni.public class DivisionExample {
public static void main(String[] args) {
int a = 10;
int b = 0;
try {
int result = divide(a, b);
System.out.println(result);
} catch (ArithmeticException e) {
System.out.println("Error: division by zero");
}
}
public static int divide(int a, int b) {
return a / b;
}
}
In questo esempio abbiamo aggiunto un costrutto try-catch per gestire l'eccezione divisione per zero. In breve, try-catch-finally è un costrutto del linguaggio di programmazione Java che consente di gestire eccezioni ed eseguire codice indipendentemente dal fatto che si sia verificata o meno un'eccezione. try-catch-finally è composto da tre blocchi:
- Il blocco prova . Qui viene eseguito codice potenzialmente pericoloso. Questo è il codice che può generare un'eccezione. Se si verifica un'eccezione all'interno di un blocco try , l'esecuzione del codice in quel blocco viene interrotta e il controllo viene trasferito al blocco catch.
- Il blocco della cattura . Qui viene gestita l'eccezione generata. Nel blocco catch è possibile specificare quale eccezione catturare e quale logica eseguire quando viene catturata. Il blocco finale . Questo viene eseguito indipendentemente dal fatto che si sia verificata o meno un'eccezione. Il blocco last viene utilizzato, ad esempio, per rilasciare le risorse (come la chiusura di un file o un socket) che erano state allocate in un blocco try. Puoi omettere questo blocco.
lancia la parola chiave
La parola chiave Throws viene utilizzata nella firma del metodo. Se è così, significa che viene generata un'eccezione nel metodo. Ciò può propagare le eccezioni nello stack di chiamate e indicare che non è necessario gestire le eccezioni nel metodo corrente. In Java, "lancia" può essere utilizzato anche per fare riferimento a eccezioni personalizzate definite in un programma. Ad esempio, un metodo può eseguire una divisione di due numeri ma lanciare un'eccezione IllegalArgumentException se il secondo argomento è zero:public static double divide(double a, double b) throws IllegalArgumentException {
if (b == 0) {
throw new IllegalArgumentException("Division by zero is not allowed");
}
return a / b;
}
Questo metodo utilizza la parola chiave Throws per indicare che è possibile lanciare un'IllegalArgumentException se il secondo argomento è null. Se tale eccezione si verifica durante l'esecuzione del metodo, verrà passata al metodo chiamante per l'elaborazione. Esempio di chiamata al metodo:
public static void main(String[] args) {
double result = 0;
try {
result = divide(10, 0);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("Result: " + result);
}
In questo esempio, il metodo divide() viene chiamato con argomenti 10 e 0, che genererà un'eccezione IllegalArgumentException perché la divisione per zero è impossibile. L'eccezione verrà intercettata da un blocco try-catch e verrà visualizzato un messaggio di errore. Il programma restituirà un valore pari a zero poiché l'eccezione termina l'esecuzione del metodo divide() .
GO TO FULL VERSION