Ha senso fare "try-finally" senza "catturare"?


127

Ho visto un codice come questo:

    try
    {
        db.store(mydata);
    }
    finally
    {
        db.cleanup();
    }

Ho pensato che trydovrebbe avere un catch?

Perché questo codice lo fa in questo modo?


1
assicura la pulizia come altre risposte menzionate, in particolare per handle di file fopeno connessione DB (anche in PHP)
MediaVince

Risposte:


182

Ciò è utile se si desidera che il metodo attualmente in esecuzione generi ancora l'eccezione consentendo al contempo di ripulire 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();
    }
}

17
comunemente usato con i blocchi come in: lock.lock (); prova {/ * bloccato * /} finalmente {lock.unlock ()}
minuti

Cosa succede se finalmente viene generata un'eccezione?
Bart

1
@barth Quando non è presente alcun catchblocco, l'eccezione generata finallyverrà eseguita prima di qualsiasi eccezione nel tryblocco. Quindi, se ci sono due eccezioni, una dentro trye una nella finallysola eccezione che verrà lanciata è quella dentro finally. Questo comportamento non è lo stesso in PHP e Python in quanto entrambe le eccezioni verranno generate contemporaneamente in questi linguaggi e l'ordine delle eccezioni è tryprima un allora finally.
Pioggia il

72

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


23
+1 Esatto. Il tryè solo lì per consentire ilfinally . Le eccezioni non vengono rilevate.
zockman,

2
+1 per chiarire che l'eccezione continua lo stack fino a quando non viene rilevata. Grazie
Code Jockey

20

Perché questo codice lo fa in questo modo?

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

Spesso, il codice di basso livello non può reagire in modo appropriato alle eccezioni perché l'utente deve essere avvisato o l'eccezione deve essere registrata o un'altra strategia deve essere provata. Il codice di basso livello svolge 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, perderebbero), quindi fa proprio questo nel file finally clausola, assicurandosi che accada sempre , indipendentemente dal fatto che sia stata generata un'eccezione.


2

Il blocco finally garantisce che anche quando viene generata una RuntimeException (forse a causa di un bug nel codice chiamato), il db.cleanup() verrà effettuata chiamata.

Questo è anche spesso usato per prevenire un eccesso di nidificazione:

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

Soprattutto quando ci sono molti punti in cui il metodo ritorna, questo migliora la leggibilità in quanto chiunque può vedere il codice di pulizia viene chiamato in ogni caso.


0

Il codice lo sta facendo per garantire che il database sia chiuso.
Di solito, il modo in cui lo faresti è inserire tutto il tuo codice di accesso al database nel blocco try e quindi effettuare una chiamata per chiudere il database nel blocco finally.
Il modo in cui try ... finally funziona, significa che il codice nel blocco try viene eseguito e il codice nel blocco finally viene eseguito al termine ... indipendentemente da cosa.
A meno che il computer non venga strappato dal muro, finalmente verrà eseguito.
Ciò significa che anche se viene chiamata un'eccezione e l'esecuzione del metodo richiede tre anni, andrà comunque nel blocco finally e il database verrà chiuso.


0

Se uno dei codici nel blocco try è in grado di generare un'eccezione controllata, deve apparire nella clausola dei tiri della firma del metodo. Se viene generata un'eccezione non selezionata, viene espulsa dal metodo.

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.