View Full Version : [JAVA] Eccezioni checked ed uncheked...mi aiutate a fare chiarezza ?!?!
D4rkAng3l
30-04-2009, 17:11
Ho da poco iniziato a studiare per un secondo esame di programmazione OO...nel programma del corso si parla di eccezioni cheked e di eccezini unchecked.
Da quello che ho capito le prime estendono la classe Exception e basta (ma non la classe Runtime Exception figlia di Exception) mentre le seconde estendono la classe RuntimeException.
Ma che significa esattamente? Che le uncheked sono eccesioni riferite ad eventi eccezionali che avvengono a runtime (che ne sò tipo provo ad accedere all'(n+1)esimo elemento di un array di n elementi e mi viene restituita una IndexOutOfBoundException) mentre le checked? Quando le uso? Ho qualche dubbio.
A logica dire che un possibile caso d'uso potrebbe essere questo: ho un metodo fact che riceve un intero e ne restituisce il fattoriale, per avere senso tale parametro deve essere >0...quindi potrei scrivere una mia eccezione checked (quindi estendendo Exception) che viene sollevata se il parametro è <= 0 e per esempio potrebbe gestirla cabiandogli segno e facendo comunque eseguire il metodo che ora potrebbe calcolare il fattoriale (se è 0 boo magari fà qualche altra cosa)...questo perchè l'evento eccezionale è stato in qualche modo previsto prima come una possibilità che potrebbe accadere...
Fila come discorso?
Poi altro dubbio...se dichiaro un'eccezione come checkd la devo dichiarare per forza nell'header della mia routine e devo per forza scrivere il codice che la gestisce, giusto?
Cos'è il mascheramento di un'eccezione? (questa cosa non l'ho proprio capita)
Grazie
Andrea
Frank1962
30-04-2009, 17:33
Detta in poche righe praticamente quando vai a creare una classe o metodo definendolo "generatore" di proabile eccezione a tempo di esecuzione hai queste due possibilità, definirlo come una Exception o come una RuntimeException:
public void method() throws Exception {
}
public void method() throws RuntimeException {
}
La differenza sostanziale è che con le Exception dai la possibilità al codice che andrà a utilizzare tale metodo/classe di catturare l'eccezione e gestirla, mentre con la RuntimeException non c'è nessuna possibilità di catturare l'eccezione a livello del codice (il famoso try{ } catch(Exception e) { }) e ti troverai l'errore solotanto a tempo di esecuzione.
Quà trovi spiegato tutto anche con dei chiari esempi ....
http://tutorials.jenkov.com/java-exception-handling/checked-or-unchecked-exceptions.html
l'eccezione non controllata può essere catturata esattamente come l'eccezione controllata e in più può essere gestita tramite un UncaughtExceptionHandler.
Detto questo in Java l'unica certezza è che i progettisti hanno introdotto le eccezioni non controllate perchè esistono condizioni di impossibilità al raggiungimento di uno scopo per un blocco di codice talmente "pervasive" che costringere ogni volta il programmatore ad usare un blocco try-catch avrebbe ammazzato il linguaggio sul nascere.
Basti pensare alla divisione in cui il divisore sia una variabile (incombe la DivisionByZeroException) o all'accesso ad un membro (la nota NullPointerException).
E' difficile trovare una sistemazione teorica per la suddivisione controllata/non controllata.
Una volta stabilito che l'eccezione è appunto una condizione di impossibilità al raggiungimento di uno scopo da parte di un blocco di istruzioni per causa esterna al blocco stesso cosa potremmo dire, che l'eccezione dev'essere controllata lo scopo del blocco se è veramente importamente? Fa un po' ridere :D.
D4rkAng3l
30-04-2009, 18:17
Detta in poche righe praticamente quando vai a creare una classe o metodo definendolo "generatore" di proabile eccezione a tempo di esecuzione hai queste due possibilità, definirlo come una Exception o come una RuntimeException:
public void method() throws Exception {
}
public void method() throws RuntimeException {
}
La differenza sostanziale è che con le Exception dai la possibilità al codice che andrà a utilizzare tale metodo/classe di catturare l'eccezione e gestirla, mentre con la RuntimeException non c'è nessuna possibilità di catturare l'eccezione a livello del codice (il famoso try{ } catch(Exception e) { }) e ti troverai l'errore solotanto a tempo di esecuzione.
Quà trovi spiegato tutto anche con dei chiari esempi ....
http://tutorials.jenkov.com/java-exception-handling/checked-or-unchecked-exceptions.html
mmm quindi praticamente mi stai dicendo che una unchecked exception non posso mai gestirla nel codice?
Mi sorgono ancora più dubbi...sul mio libro dice che le checked exception devo per forza gestirle scrivendo il codice che gestisce la situazione eccezionale altrimenti avrò un errore in fase di compilazione ma non mi dice che è vietato fare try catcth con le unchecked exception...anzi riporta questo codice d'esempio:
try{ x = y[n];}
catch(IndexOutOfBoundsException e){
// CODICE CHE GESTISCE IndexOutOfBoundsException
}
i = Array.search(z,x)
La IndexOutOfBoundsException non dovrebbe essere una unchecked exception? Però quì la sta gestendo...
Come mai?
Grazie
Andrea
Tu, puoi gestire entrambi i tipi di eccezioni, catturandole.
Nel caso delle unchecked, non sei costretto a gestirle, nel senso che non è necessario ogni due righe verificare con un try-catch una NullPointerException.
Invece sei costretto* a gestire con un try-catch l'altro tipo di eccezioni tipo:
try{
...
metodoCheSeNeFrega();
..
}catch(IOException){System.out.println("eccezione catturata");}
*In realtà, potresti in questo caso non mettere un try-catch piuttosto mettere nel metodo scatenante l'eccezionethrows IOException che di fatto dice "non mi interessa di gestire ora l'eccezione, se ne occupino i metodi di livello più alto"
Faccio l'esempio:
void metodoCheGestisce(){
try{
void metodoCheSeNeFrega();
}catch(IOException){System.out.println("hai cercato di convertire una stringa che non è un numero);}
void metodoCheSeNeFrega() throws IOException{
throw new IOException();
}
Spero di essere stato chiaro quando dico metodo di livello più alto (nell'esempio metodoCheGestisce())
cdimauro
30-04-2009, 21:21
Se vuoi approfondire l'argomento, ci sono un paio di link:
Does Java need Checked Exceptions? (http://www.mindview.net/Etc/Discussions/CheckedExceptions)
The Trouble with Checked Exceptions (http://www.artima.com/intv/handcuffs.html)
||ElChE||88
30-04-2009, 21:34
Invece sei costretto* a gestire con un try-catch l'altro tipo di eccezioni tipo:
Peccato che la NumberFormatException sia unchecked.
Peccato che la NumberFormatException sia unchecked.
oops hai ragione :D
correggo l'esempio. però la spiegazione spero resti valida :)
Frank1962
01-05-2009, 04:17
Come mai?
Grazie
Andrea
perchè aveva torto! :D ....mi domando comunque cosa succede se ho un classe/libreria non documentata, come faccio a capire quali classi/metodi dovrei gestire con una try{ }catch{} nell'eventualità che mi dovessero generare questo tipo di Exception....
D4rkAng3l
01-05-2009, 09:47
Tu, puoi gestire entrambi i tipi di eccezioni, catturandole.
Nel caso delle unchecked, non sei costretto a gestirle, nel senso che non è necessario ogni due righe verificare con un try-catch una NullPointerException.
Invece sei costretto* a gestire con un try-catch l'altro tipo di eccezioni tipo:
try{
...
metodoCheSeNeFrega();
..
}catch(IOException){System.out.println("eccezione catturata");}
*In realtà, potresti in questo caso non mettere un try-catch piuttosto mettere nel metodo scatenante l'eccezionethrows IOException che di fatto dice "non mi interessa di gestire ora l'eccezione, se ne occupino i metodi di livello più alto"
Faccio l'esempio:
void metodoCheGestisce(){
try{
void metodoCheSeNeFrega();
}catch(IOException){System.out.println("hai cercato di convertire una stringa che non è un numero);}
void metodoCheSeNeFrega() throws IOException{
throw new IOException();
}
Spero di essere stato chiaro quando dico metodo di livello più alto (nell'esempio metodoCheGestisce())
In pratica qui mi stai dicendo:
try{
...
metodoCheSeNeFrega();
..
}catch(IOException){System.out.println("eccezione catturata");}
mmm temo di non aver capito bene cosa intendi quì sigh :confused:
khelidan1980
01-05-2009, 18:36
perchè aveva torto! :D ....mi domando comunque cosa succede se ho un classe/libreria non documentata, come faccio a capire quali classi/metodi dovrei gestire con una try{ }catch{} nell'eventualità che mi dovessero generare questo tipo di Exception....
Eclipse? :D
O comunque se non gestisci una checked non compila
In pratica qui mi stai dicendo:
try{
...
metodoCheSeNeFrega();
..
}catch(IOException){System.out.println("eccezione catturata");}
mmm temo di non aver capito bene cosa intendi quì sigh :confused:
Li intendevo farti capire che nel primo metodo
metodoCheSeNeFrega()
non gestivi l'eccezione, ma ammettevi che poteva generare un 'eccezione.
Nel secondo,
metodoCheGestisce()
invece, l'hai gestita tramite un try-catch.
bye
banryu79
04-05-2009, 08:53
Provo a fare un riassunto schematico?
La mamma di tutte le eccezioni:
java.lang.Throwable
The Throwable class is the superclass of all errors and exceptions in the Java language. Only objects that are instances of this class (or one of its subclasses) are thrown by the Java Virtual Machine or can be thrown by the Java throw statement. Similarly, only this class or one of its subclasses can be the argument type in a catch clause.
Un primo figliuolo, che non si vede in giro molto spesso:
java.lang.Error (extends java.lang.Throwable)
Lasciamolo stare, per il momento.
L'altra figlia, sorella di Error e molto più famosa:
java.lang.Exception (extends java.lang.Throwable)
The class Exception and its subclasses are a form of Throwable that indicates conditions that a reasonable application might want to catch.
Questa ragazza ha moltissimi figli.
Normalmente un figlio di Exception che viene lanciato da un metodo, deve per forza essere gestito al livello del chiamante di quel metodo, in un blocco try-catch.
Il chiamante può gestire la situazione come vuole, ma deve catturare l'eccezione.
Queste sono le eccezioni "checked".
Tra tutte le numerosissime figlie che Exception ha generato nel clan del JDK, una in particolare è la pecora nera della famiglia:
java.lang.RuntimeException (extends Exception)
RuntimeException is the superclass of those exceptions that can be thrown during the normal operation of the Java Virtual Machine.
A method is not required to declare in its throws clause any subclasses of RuntimeException that might be thrown during the execution of the method but not caught.
Un metodo che lancia codesta eccezione o le eccezioni che l'hanno come madre non obbliga il chiamante a catturarla con il costrutto try-catch: il chiamante è libero di non catturarla, se invece vuole può catturarla e gestirla come meglio crede.
In pratica queste sono le eccezioni "unchecked".
banryu79
04-05-2009, 09:17
Facciamo un esempio della differenza tra eccezioni "checked" e "unchecked" dal punto di vista del chiamante.
Supponiamo di dover istanziare un oggetto di tipo java.io.FileInputStream.
Usiamo il costruttore che prende come parametro una String, che rappresenta il "path name" del file:
FileInputStream(String name)
Creates a FileInputStream by opening a connection to an actual file, the file named by the path name name in the file system.
Ora, consultando i javadoc notiamo che il metodo costruttore potrebbe lanciare due eccezioni:
public FileInputStream(String name) throws FileNotFoundException
Creates a FileInputStream by opening a connection to an actual file, the file named by the path name name in the file system. A new FileDescriptor object is created to represent this file connection.
First, if there is a security manager, its checkRead method is called with the name argument as its argument.
If the named file does not exist, is a directory rather than a regular file, or for some other reason cannot be opened for reading then a FileNotFoundException is thrown.
Parameters:
name - the system-dependent file name.
Throws:
FileNotFoundException - if the file does not exist, is a directory rather than a regular file, or for some other reason cannot be opened for reading.
SecurityException - if a security manager exists and its checkRead method denies read access to the file.
La domanda è: dobbiamo catturarle?
Consultando i javadoc per la classe FileNotFoundException si scopre che questa estende IOException la quale estende Exception: abbiamo dunque a che fare con un'eccezione "checked", dobbiamo quindi catturarla (inoltre notiamo che è citata nella clausola throws del metodo stesso).
Consultiamo ora i javadoc per la classe SecurityException, e scopriamo così che essa estende RuntimeException: dunque è di tipo "unchecked", e non siamo obbligati a catturarla (però potremmo volerlo fare lo stesso, la scelta è nostra).
Il codice che istanzierà il nostro oggetto FileInputStream dovrà quindi gestire il caso in cui viene lanciata una FileNotFoundException, invece pe la SecurityException non occorre fare nulla: scegliamo di non gestirla, in questo caso.
String filePath = "un file path espresso come stringa e ricavato in qualche modo dall'applicazione";
...
...
FileInputStream fileStream = null;
try
{
fileStream = new FileInputStream(filePath);
// seguono istruzioni che utilizzano il file aperto
...
}
catch (FileNotFoundException ex)
{
// segue gestione dell'eccezione che dipende da come si
// vuole gestire la faccenda
...
}
banryu79
04-05-2009, 09:33
Per concludere, ti linko delle info utili (tutorial dal sito della Sun) su come creare/lanciare le proprie eccezioni (tutto in inglese ovviamente):
- How to Throw Exceptions (http://java.sun.com/docs/books/tutorial/essential/exceptions/throwing.html)
- Creating Exception Classes (http://java.sun.com/docs/books/tutorial/essential/exceptions/creating.html)
queste sopra sono solo due parti diell'intero argomento:
- Lesson: Exceptions (http://java.sun.com/docs/books/tutorial/essential/exceptions/creating.html)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.