Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Nioh 3: souls-like punitivo e Action RPG
Nioh 3: souls-like punitivo e Action RPG
Nioh 3 aggiorna la formula Team NINJA con aree esplorabili più grandi, due stili di combattimento intercambiabili al volo (Samurai e Ninja) e un sistema di progressione pieno di attività, basi nemiche e sfide legate al Crogiolo. La recensione entra nel dettaglio su combattimento, build, progressione e requisiti PC
Test in super anteprima di Navimow i220 LiDAR: il robot tagliaerba per tutti
Test in super anteprima di Navimow i220 LiDAR: il robot tagliaerba per tutti
La facilità di installazione e la completa automazione di tutte le fasi di utilizzo, rendono questo prodotto l'ideale per molti clienti. Ecco com'è andata la nostra prova in anteprima
Dark Perk Ergo e Sym provati tra wireless, software via browser e peso ridotto
Dark Perk Ergo e Sym provati tra wireless, software via browser e peso ridotto
be quiet! debutta nel settore mouse da gaming con Dark Perk Ergo e Dark Perk Sym: due modelli gemelli per specifiche, con polling rate di 8.000 Hz anche in wireless, sensore PixArt PAW3950 da 32.000 DPI e autonomia dichiarata fino a 110 ore. Nel test, a 8.000 Hz si arriva a circa 30 ore reali, con ricarica completa in un'ora e mezza
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 09-04-2008, 10:30   #1
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2787
[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();
   }
}
Ok, con questo ho capito cosa fa finally ma non avrei potuto fare la stessa cosa così?
Codice:
public void insertInDB(){
   try{
      cmd.executeUpdate("INSERT INTO...");
   }catch(SQLException exc){
      exc.printStackTrace();
   }
   connection.close();
}
E' questo che non capisco... Grazie a chi mi illuminerà!
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 09-04-2008, 10:55   #2
khelidan1980
Senior Member
 
L'Avatar di khelidan1980
 
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
khelidan1980 è offline   Rispondi citando il messaggio o parte di esso
Old 09-04-2008, 11:06   #3
shinya
Senior Member
 
L'Avatar di shinya
 
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
Quote:
Originariamente inviato da khelidan1980 Guarda i messaggi
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
No, non è vero.

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...
In questo caso può anche scrivere come ha fatto, ma è uno stile che non consiglio per diversi motivi:
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!

Ultima modifica di shinya : 09-04-2008 alle 11:10.
shinya è offline   Rispondi citando il messaggio o parte di esso
Old 09-04-2008, 11:16   #4
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2787
Quote:
Originariamente inviato da shinya Guarda i messaggi
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'.
1) Sì, è vero, poco più avanti nel libro aggiunge anche questa correzione, era per fare un esempio semplice.
2) Adesso ho capito e ha tutto più senso.
Grazie mille!
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 09-04-2008, 11:32   #5
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
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
}
In questo caso p.es. io propago l'eccezione al chiamante, ma la connessione al DB sara' correttamente chiusa in tutti i casi.
__________________
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.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 09-04-2008, 11:33   #6
khelidan1980
Senior Member
 
L'Avatar di khelidan1980
 
Iscritto dal: Mar 2005
Città: Morimondo city
Messaggi: 5491
Quote:
Originariamente inviato da shinya Guarda i messaggi
No, non è vero.
Già ho scritto una cavolata,son fuso pure io alle 11 di mattina mah
__________________
Khelidan
khelidan1980 è offline   Rispondi citando il messaggio o parte di esso
Old 09-04-2008, 11:57   #7
vladix
Member
 
L'Avatar di vladix
 
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{

  }
nel caso nn si voglia gestire la eccezione in "questo metodo" si puo definire un blocco composto solo di try/finally
Codice:
  try{
 
    return;
  }finnaly{

  }
Quote:
Originariamente inviato da wingman87 Guarda i messaggi
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();
   }
}
Ok, con questo ho capito cosa fa finally ma non avrei potuto fare la stessa cosa così?
Codice:
public void insertInDB(){
   try{
      cmd.executeUpdate("INSERT INTO...");
   }catch(SQLException exc){
      exc.printStackTrace();
   }
   connection.close();
}
E' questo che non capisco... Grazie a chi mi illuminerà!
nel primo caso la connessione verra chiusa sempre , mentre nel secondo caso solo quando il try non genera un eccezione ( in entrabi i casi dovrai cmq gestire l'eccezione generata dal metodo conection.close() )questo discorso vale nel caso tu vuoi rilanciare l'eccezione ... se no non ha molto senso il finnally xche dopo la clausola catch , il tuo programma (metodo) continuera a funzionare normalmente

Ultima modifica di vladix : 09-04-2008 alle 12:07.
vladix è offline   Rispondi citando il messaggio o parte di esso
Old 09-04-2008, 12:07   #8
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Quote:
Originariamente inviato da vladix Guarda i messaggi
... il finally non serve a propagare errori ... e un concetto (secondo me e forse nn solo) sbagliato ,
Io non ho detto che il finally serve per propagare errori.
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.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 09-04-2008, 12:22   #9
vladix
Member
 
L'Avatar di vladix
 
Iscritto dal: Jan 2008
Città: roma
Messaggi: 296
Quote:
Originariamente inviato da gugoXX Guarda i messaggi
i o in presenza di risorse che richiedono chiusure (file, etc.)
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 )
vladix è offline   Rispondi citando il messaggio o parte di esso
Old 09-04-2008, 12:26   #10
shinya
Senior Member
 
L'Avatar di shinya
 
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
Quote:
Originariamente inviato da vladix Guarda i messaggi
nel caso nn si voglia gestire la eccezione in "questo metodo" si puo definire un blocco composto solo di try/finally
Codice:
  try{
 
    return;
  }finnaly{

  }
Questa non l'ho capita. Cosa vorresti fare nel 'finally' che non puoi fare prima del 'return'?
shinya è offline   Rispondi citando il messaggio o parte di esso
Old 09-04-2008, 12:27   #11
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2787
Quote:
Originariamente inviato da gugoXX Guarda i messaggi
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.)
In effetti prima di postare avevo notato questa possibilità del finally, ma non ne vedevo l'utilità (non che adesso la veda), quindi ho aperto questo thread.
Vi ringrazio tutti, adesso penso di aver capito a fondo l'utilità del finally.
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 09-04-2008, 12:31   #12
shinya
Senior Member
 
L'Avatar di shinya
 
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
Quote:
Originariamente inviato da vladix Guarda i messaggi
ma cmq il finnaly viene eseguito anche se c'e il return "in mezzo" (subito prima del return ) [...CUT...]
Prima del 'return' dici?
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;
    }
  }
}
shinya è offline   Rispondi citando il messaggio o parte di esso
Old 09-04-2008, 12:32   #13
vladix
Member
 
L'Avatar di vladix
 
Iscritto dal: Jan 2008
Città: roma
Messaggi: 296
Quote:
Originariamente inviato da shinya Guarda i messaggi
Questa non l'ho capita. Cosa vorresti fare nel 'finally' che non puoi fare prima del 'return'?
semplicemente
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)
  }
vladix è offline   Rispondi citando il messaggio o parte di esso
Old 09-04-2008, 12:36   #14
vladix
Member
 
L'Avatar di vladix
 
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.
vladix è offline   Rispondi citando il messaggio o parte di esso
Old 09-04-2008, 13:28   #15
beppegrillo
Senior Member
 
L'Avatar di beppegrillo
 
Iscritto dal: Mar 2004
Messaggi: 1455
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~
beppegrillo è offline   Rispondi citando il messaggio o parte di esso
Old 11-10-2014, 16:22   #16
Samaritan
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.
Samaritan è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Nioh 3: souls-like punitivo e Action RPG Nioh 3: souls-like punitivo e Action RPG
Test in super anteprima di Navimow i220 LiDAR: il robot tagliaerba per tutti Test in super anteprima di Navimow i220 LiDAR: i...
Dark Perk Ergo e Sym provati tra wireless, software via browser e peso ridotto Dark Perk Ergo e Sym provati tra wireless, softw...
DJI RS 5: stabilizzazione e tracking intelligente per ogni videomaker DJI RS 5: stabilizzazione e tracking intelligent...
AMD Ryzen 7 9850X3D: Zen 5, 3D V-Cache e frequenze al top per il gaming AMD Ryzen 7 9850X3D: Zen 5, 3D V-Cache e frequen...
Svelata la Xiaomi YU7 GT: kit wide body ...
Svelati gli amiibo di Resident Evil Requ...
Nigeria prima nazione africana a produrr...
QuakeCon 2026: anniversario storico per ...
SSD NVMe M.2 e Pentium III insieme? Si.....
Un altro iPhone economico è in arrivo a ...
Svolta Polestar per la ricarica: Plug&am...
QNAP lancia myQNAPcloud One: l'archiviaz...
Clamoroso in Formula 1: FIA pronta a cam...
L'UE dà ragione ad Apple: Maps e ...
Droni accecati e comunicazioni isolate: ...
Accesso alla memoria su Windows 11 solo ...
Regali di San Valentino: 15 idee tech sf...
Stellantis a picco in Borsa: 22 miliardi...
Baldur's Gate 3 diventa una serie TV: pr...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 14:50.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v