2010-04-10 14 views

risposta

130

Ciò è utile se si desidera che il metodo attualmente in esecuzione continui a generare l'eccezione consentendo al tempo stesso di pulire le risorse in modo appropriato. Di seguito è riportato un esempio concreto di gestione dell'eccezione da un metodo di chiamata.

public void yourOtherMethod() { 
    try { 
     yourMethod(); 
    } catch (YourException ex) { 
     // handle exception 
    } 
}  

public void yourMethod() throws YourException { 
    try { 
     db.store(mydata); 
    } finally { 
     db.cleanup(); 
    } 
} 
+10

comunemente usato con i blocchi come in: lock.lock(); prova {/ * locked * /} finally {lock.unlock()} – mins

60

E 'lì perché il programmatore ha voluto assicurarsi che db.cleanup() è chiamato anche se il codice all'interno del blocco try genera un'eccezione. Eventuali eccezioni non verranno gestite da quel blocco, ma verranno propagate solo verso l'alto dopo l'esecuzione del blocco finally.

+15

+1 Esattamente. Il 'try' è solo lì per consentire il' finalmente'. Le eccezioni non vengono catturate. – zockman

+0

@zockman Il tuo commento lo ha inchiodato. –

+1

+1 per chiarire che l'eccezione continua fino allo stack finché non viene catturato. Grazie –

18

Perché questo codice farlo in questo modo?

Perché apparentemente il codice non sa come gestire le eccezioni a questo livello. Questo va bene - fino a quando uno dei chiamanti lo fa, vale a dire fino a quando l'eccezione viene in definitiva gestita da qualche parte.

Spesso, codice di basso livello non può reagire adeguatamente eccezioni perché l'utente deve essere informato, oppure l'eccezione deve essere registrato, o un'altra strategia deve essere provato. Il codice di basso livello esegue una sola funzione e non conosce il processo decisionale di livello superiore.

Ma il codice ha ancora bisogno di ripulire le sue risorse (perché se non lo fa, avrebbero perdite), in modo che fa proprio questo nella clausola finally, facendo in modo che essa sempre accade, se un'eccezione è stata lanciato o no.

2

Il blocco finally assicura che anche quando viene lanciata una RuntimeException (forse a causa di qualche bug nel codice chiamato), verrà effettuata la chiamata db.cleanup().

Questo è anche spesso usato per prevenire troppo nidificazione:

try 
{ 
    if (foo) return false; 
    //bla ... 
    return true; 
} 
finally 
{ 
    //clean up 
} 

Soprattutto quando ci sono molti punti in cui il metodo restituisce, questo migliora la leggibilità come chiunque può vedere il codice pulizia viene chiamato in tutti i casi .

0

Il codice sta facendo per assicurare che il database sia chiuso.
In genere, il modo in cui lo si fa è inserire tutto il codice di accesso al database nel blocco try, quindi effettuare una chiamata per chiudere il database nel blocco finally.
Il modo in cui try ... finalmente funziona, significa che il codice nel blocco try viene eseguito e il codice nel blocco finally viene eseguito quando termina ... non importa cosa.
Non appena il computer viene tirato fuori dal muro, alla fine verrà eseguito.
Ciò significa che anche se viene richiamata un'eccezione e il metodo richiede tre anni, verrà comunque inserito nel blocco finally e il database verrà chiuso.

0

Se uno qualsiasi dei codici nel blocco try può generare un'eccezione controllata, deve comparire nella clausola throws della firma del metodo. Se viene generata un'eccezione non controllata, viene fuori dal metodo.

Il blocco finally viene sempre eseguito, indipendentemente dal fatto che venga generata o meno un'eccezione.