|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2780
|
[JAVA] Quando si usa finally?
Ho capito come funziona finally però non ho trovato esempi in cui il suo utilizzo sia necessario. Sul libro che sto leggendo c'è l'esempio seguente:
Codice:
public void insertInDB(){
try{
cmd.executeUpdate("INSERT INTO...");
}catch(SQLException exc){
exc.printStackTrace();
}finally{
connection.close();
}
}
Codice:
public void insertInDB(){
try{
cmd.executeUpdate("INSERT INTO...");
}catch(SQLException exc){
exc.printStackTrace();
}
connection.close();
}
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Mar 2005
Città: Morimondo city
Messaggi: 5491
|
no perchè in quel caso se viene sollevata l'eccezione l'esecuzione non arriva a quel punto ma viene ritornato il controllo al main,finally serve per l'appunto in caso di eccezione viene eseguito il codice compreso nel blocco finnaly prima di ritornare il controllo al main
__________________
Khelidan |
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
|
Quote:
Codice:
class FinallyTest {
public static void main(String[] args) {
testFinally();
}
private static void testFinally() {
try {
System.out.println("Try...");
throw new Exception();
} catch (Exception ex) {
System.out.println("Catch...");
}
System.out.println("Finally...");
}
}
$> java FinallyTest
Try...
Catch...
Finally...
Ad esempio: 1) nel mondo reale "connection.close()" lancia anch'essa una SQLException, e va gestita. 2) nell'esempio fai solo il printStackTrace dell'eccezione...se ti accontenti va pure bene...ma in realtà quello che vuoi fare è incapsulare l'eccezione in un tipo con un livello di astrazione più alto e rilanciarla. Quindi o ti gestisci la chiusura della connessione nel 'catch' (gestendo anche l'ulteriore SQLException) o usi 'finally'. Edit: scusate l'errore semantico...ho chiamato la classe FinallyTest e ho stampato a console "finally..." e non c'è nessuna clausola 'finally'...mah! son proprio fuso!
__________________
-> The Motherfucking Manifesto For Programming, Motherfuckers Ultima modifica di shinya : 09-04-2008 alle 11:10. |
|
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2780
|
Quote:
2) Adesso ho capito e ha tutto più senso. Grazie mille! |
|
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Il finally serve effettivamente solo quando serve "Propagare" l'eccezione all'esterno, senza la quale il codice sarebbe bruttino.
Scrivo pseudocodice: Codice:
try
{
Db.ConnectionOpen
Db.FaiqualcosaColDatabase
Db.Commit
}
Catch
{
Db.RollBack
Throw Exception all'esterno.
}
Finally
{
Db.CloseConnection
}
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Mar 2005
Città: Morimondo city
Messaggi: 5491
|
Già ho scritto una cavolata,son fuso pure io alle 11 di mattina mah
__________________
Khelidan |
|
|
|
|
|
#7 | |
|
Member
Iscritto dal: Jan 2008
Città: roma
Messaggi: 296
|
... il finally non serve a propagare errori ... e un concetto (secondo me e forse nn solo) sbagliato , il finally racchiude un pezzo di codice che dovra essere eseguito a prescindere dal fatto che e il codice nel try ha generato o no errori , (ad esempio si vuole chiudere una connessione sia che la transazione e andata a buon fine o meno , oppure un quando si ha aperto un socket , un file ... ) perche il finally e sempre eseguito (sempre) , anche quando c'e la clausola return nel try
Codice:
try{
return;
}catch(Exception e){
}finnaly{
}
Codice:
try{
return;
}finnaly{
}
Quote:
Ultima modifica di vladix : 09-04-2008 alle 12:07. |
|
|
|
|
|
|
#8 | |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Quote:
Ho solo detto che il finally lo si usa praticamente solo quando si vogliono propagare gli errori per i quali si e' scritto il costrutto try-catch volendo pero' ritirare correttamente le risorse. Negli altri casi se ne puo' fare a meno, come ha anche evidenziato Shinya. L'esempio del return in mezzo e' fuorviante. Spero che nessuno piazzi return in mezzo alle funzioni, soprattutto durante transazioni o in presenza di risorse che richiedono chiusure (file, etc.)
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
|
|
|
|
|
|
#9 |
|
Member
Iscritto dal: Jan 2008
Città: roma
Messaggi: 296
|
ma cmq il finnaly viene eseguito anche se c'e il return "in mezzo" (subito prima del return ) xcio e legale dichiarare return nel try , ( ovviamente in certi casi e proprio brutto ma quando in un metodo si esegue solo codice "pericoloso" quindi tuto chiuso nel try e il catch rilancia l'eccezione ... certo nessuno vieta mettere il return alla fine del metodo anche in questo caso , ( forse dipende anche dallo stile che uno si abitua a usare )
|
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
|
Questa non l'ho capita. Cosa vorresti fare nel 'finally' che non puoi fare prima del 'return'?
__________________
-> The Motherfucking Manifesto For Programming, Motherfuckers |
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2780
|
Quote:
Vi ringrazio tutti, adesso penso di aver capito a fondo l'utilità del finally. |
|
|
|
|
|
|
#12 | |
|
Senior Member
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
|
Quote:
Cosa stampa questo codice allora? Codice:
class FinallyTest2 {
public static void main(String[] args) {
System.out.println(test());
}
private static boolean test() {
try {
return true;
} finally {
return false;
}
}
}
__________________
-> The Motherfucking Manifesto For Programming, Motherfuckers |
|
|
|
|
|
|
#13 | |
|
Member
Iscritto dal: Jan 2008
Città: roma
Messaggi: 296
|
Quote:
Codice:
try{
//codice pericoloso
return qualcosa;
}finally{
// codice da eseguire anche se il try lancia un eccezione (che ovviamente sara gestita ad un livello + alto)
}
|
|
|
|
|
|
|
#14 |
|
Member
Iscritto dal: Jan 2008
Città: roma
Messaggi: 296
|
beh , il finnaly viene sempre eseguito e quindi stampera false
Edit: e cmq nn e che o inventato io il blocco try/finnaly , io ho detto solo che legale , poi dipende dalle esigenze ( quando meno te lo aspetti puo tornare utile Ultima modifica di vladix : 09-04-2008 alle 12:42. |
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Mar 2004
Messaggi: 1451
|
I finally lo usi per rilasciare risorse che hai acquisito, e che dovrai liberare indipendentemente dal fatto che il tuo programma ha lanciato o meno un'eccezione.
Il libro ti ha fatto l'esempio di una connessione al DB, poteva essere anche un file o qualsiasi altra cosa.
__________________
Ciao ~ZeRO sTrEsS~ |
|
|
|
|
|
#16 |
|
Junior Member
Iscritto dal: Jan 2004
Messaggi: 29
|
Il blocco finally{...} serve a garantire la sua esecuzione indipendentemente dal fatto che si generi un'eccezione.
E' quindi fondamentale in tutti i casi in cui si deve necessariamente rilasciare una risorsa come ad esempio una connessione ad un db od un Socket o più in generale uno Stream. Tutti oggetti che sono implicitamente associati ad una connessione o ad un flusso di trasferimento dati. Quando si ha a che fare con questo tipo di oggetti e non si usa un blocco finally, nel 99% dei casi si avrà a che fare con quel tipo di bug più difficili da individuare e che ti fanno bloccare tutto il programma senza neanche avere una eccezione che ti fa capire in modo chiaro la causa del blocco stesso. Questo perché ogni volta che si usa un costrutto try...catch si lasciano al flusso di esecuzione automaticamente due sole strade tra loro mutuamente esclusive: 1-Va tutto correttamente, quindi il blocco del catch non viene proprio eseguito. 2-Si genera l'eccezione ed il blocco del catch viene eseguito, ma tutto il resto non viene eseguito perché il flusso viene bloccato dal catch e sale verso il chiamante. Quindi se si decide di rilasciare una risorsa direttamente nel catch, questa sarà effettivamente rilasciata se e solo se si genera l'eccezione, ma se tutto va correttamente la risorsa non viene rilasciata! Questo implica uno spazio occupato in memoria che rimarrà occupato e questo accadrà ogni volta che sarà rieseguito il codice che sta nel try senza che si generi alcuna eccezione. Ecco perché il costrutto finally{} ci viene in aiuto e ci permette di rilasciare una risorsa sempre e comunque: sia che si generi un'eccezione e sia che vada tutto correttamente. In generale si può esemplificare dicendo che il costrutto finally serve ogni qual volta si ha la necessità di eseguire un certo codice indipendentemente dal flusso di esecuzione. Questa situazione si verifica sempre quando si ha a che fare con gli oggetti che ho citato prima e cioè con tutti quegli oggetti che sono intrinsecamente associati a flussi di dati che in quanto tali richiedono l'allocazione di buffer in memoria. Credimi: se non si usa il finally con questo tipo di oggetti ci si garantisce ore ed ore e forse giorni di esaurimento nervoso per capire la causa di un blocco che prima o poi arriverà. Ultima modifica di Samaritan : 11-10-2014 alle 21:15. |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 12:58.




















