Una eccezione è una situazione imprevista che il flusso di un’applicazione
può incontrare e che può essere gestita.
Un errore è una situazione imprevista non dipendente da un errore commesso
dallo sviluppatore e non può essere gestito.
Errori ed eccezioni derivano da Throwable.
Tutti gli Errori derivano da Error.
Tutte le eccezioni derivano da Exception.
Se JAVA si imbatte in un'eccezione la "lancia", interrompendo
l'esecuzione e stampando a video l'errore:
public class Principale {
public static void main(String[] args) {
int a=1;
int b=0;
System.out.println(a/b);
}
}
Exception
in thread "main" java.lang.ArithmeticException: / by zero
at Principale.main(Principale.java:5)
L’eccezione può essere gestita con un try
catch :
try {
System.out.println(a/b);
}
catch
(ArithmeticException exc) {
System.out.println("Divisione per ZERO");
}
}
L’eccezione dichiarata (ArithmeticException) deve essere quella
giusta altrimenti il catch non la cattura.
Le eccezioni sono polimorfe e quindi si
può dichiarare e catturare una eccezione superiore :
try {
System.out.println(a/b);
}
catch (Exception
exc) {
System.out.println("eccezione generica");
}
}
Si possono dichiarare varie eccezioni e
così discrimnare la gestione a seconda dell’eccezione catturata:
try {
System.out.println(a/b);
}
catch
(ArithmeticException exc) {
System.out.println("Divisione per
ZERO ");
}
catch
(NullPointerException exc) {
System.out.println("riferimento
nullo");
}
catch (Exception
exc) {
System.out.println("eccezione generica");
}
In questo caso l’ordine è importante, il
catch che entra in azione è quello scritto per primo.
finally indica un blocco che deve
essere sempre eseguito, sia se c’è una eccezione oppure no :
try {
System.out.println(a/b);
}
catch
(ArithmeticException exc) {
System.out.println("divisione per zero");
}
catch
(NullPointerException exc) {
System.out.println("riferimento nullo");
}
catch (Exception
exc) {
System.out.println("eccezione
generica");
}
finally { System.out.println("Tentativo di
operazione"); }
Eccezione personalizzata :
public class PersonalizzataException extends Exception {
public
PersonalizzataException() {
super("Problema
personalizzato");
}
public String toString() {
return getMessage() + ": messaggio
personalizzato";
}
}
si lancia in modo diretto:
public class Principale {
public static void main(String[] args) throws
PersonalizzataException {
boolean controllo = true;
if (controllo){
PersonalizzataException
eccezione = new PersonalizzataException();
throw eccezione;
}
}
}
Si può anche scrivere
in modo compatto: throw new
PersonalizzataException();
e si ottiene:
Exception in thread "main"
Problema personalizzato: messaggio personalizzato
at Principale.main(Principale.java:5)
Perché creare eccezioni personalizzate?
Consideriamo questo codice :
public class ClasseProblematica {
public ClasseProblematica(int a) {
try {
metodo(a);
}
catch
(PersonalizzataException e) {
System.out.println("errore
gravissimo!!!");
}
}
public void metodo(int a) throws
PersonalizzataException {
if (a > 1) {
throw new
PersonalizzataException();
}
}
}
public class PersonalizzataException extends Exception {
public
PersonalizzataException() {
super("Problema
personalizzato");
}
public String toString() {
return getMessage() + ": messaggio
personalizzato";
}
}
public class Principale {
public static void main(String[] args) {
for (int i = 0;i<3;i++){
ClasseProblematica
cp = new
ClasseProblematica(i);
System.out.println("tutto
benissimo con "+i);
}
}
}
In questo caso pur catturando l’eccezione
nel metodo il risultato non è buono perché si prosegue nell’elaborazione:
tutto benissimo con 0
tutto benissimo con 1
errore gravissimo!!!
tutto benissimo con 2
A questo punto entra in campo la
forza di JAVA, consentendo la propagazione dell’eccezione; l’eccezione non deve
essere catturata per forza dove si produce ma anche esternamente, consentendo
una gestione molto migliore del flusso di lavoro:
public class ClasseProblematica {
public ClasseProblematica(int a) throws
PersonalizzataException{
metodo(a);
}
public void metodo(int a) throws
PersonalizzataException {
if (a > 1) {
throw new
PersonalizzataException();
}
}
}
public class Principale {
public static void main(String[] args) {
for (int i = 0; i < 3;
i++) {
try {
ClasseProblematica cp
= new
ClasseProblematica(i);
System.out.println("tutto
benissimo con " + i);
}
catch
(PersonalizzataException e) {
System.out.println("errore
gravissimo!!!");
}
}
}
}
tutto benissimo con 0
tutto benissimo con 1
errore gravissimo!!!
Con la
clausola throws nella dichiarazione del metodo, in pratica è come se
avvertissimo il compilatore che siamo consapevoli che il metodo possa lanciare
al runtime la PersonalizzataException, e di non “preoccuparsi”,
perché gestiremo in un’altra parte del codice l’eccezione. Se un metodo
“chiamante” vuole utilizzare un altro metodo “daChiamare” che dichiara con una clausola throws il possibile
lancio di un certo tipo di eccezione, allora, il metodo “chiamante”, o deve gestire l’eccezione con un blocco try
– catch che include la chiamata
al metodo “daChiamare”, o deve dichiarare anch’esso
una clausola throws alla stessa eccezione.
Nessun commento:
Posta un commento