2011-09-27 8 views
9

Ho provato con diverse catture successive. Ho un codice "cleanup" che dovrebbe essere eseguito solo se è stata lanciata un'eccezione. Potrei aggiungere lo stesso codice ad ogni eccezione, ma questo diventa un incubo di manutenzione. Fondamentalmente, mi piacerebbe qualcosa di simile alla dichiarazione finale, ma per farlo funzionare solo se viene lanciata un'eccezione.Come eseguire il codice solo se è stata generata un'eccezione?

È possibile?

+0

Questi errori di runtime che si stanno rilevando o i propri errori aziendali. – Shahzeb

+0

IOException, ClientProtocolException, UnsupportedEncodingException, ecc. – Bromide

risposta

18

Purtroppo non esiste un supporto diretto per questo. Che ne dite di qualcosa di simile

boolean successful = false; 
try { 
    // do stuff 
    successful = true; 
} catch (...) { 
    ... 
} finally { 
    if (!successful) { 
     // cleanup 
    } 
} 
1

L'unica cosa che mi viene in mente è quello di impostare una variabile in ciascuna cattura e quindi verificare la presenza di quella variabile in fine.

Pseudocodice:

Boolean caught = false; 

try { 

    //risky code here 

catch(err) { 
    caught = true; 
    // Do other stuff 
} 
catch(err) { 
    caught = true; 
    // Do other stuff 
} 
catch(err) { 
    caught = true; 
    // Do other stuff 
} 
finally { 
    if (caught) { 
     // Do clean up 
    } 

} 
0

Perché non basta usare semplice tentativo & cattura?

try 
{ 
    foo(); 
} 
catch(Exception1 e1) 
{ 
    dealWithError(1); 
} 
catch(Exception2 e2) 
{ 
    dealWithError(2); 
} 
catch(Exception3 e3) 
{ 
    dealWithError(3); 
} 

... 

private void dealWithError(int i) 
{ 
    if(i == 1) // deal with Exception1 
    else if(i == 2) // deal with Exception2 
    else if(i == 3) // deal with Exception3 
} 
+2

esattamente ciò che nessun corpo dovrebbe mai fare. Incubo in 'se' street. – Shahzeb

1

potrei aggiungere lo stesso codice per ciascuna eccezione, ma che diventa un incubo di manutenzione.

O se cancellare il 'eccezione':

potrei aggiungere lo stesso codice per ogni [luogo], ma che diventa un incubo di manutenzione.

Questo è ciò che i metodi sono fatti per.

private void cleanup() { /* clean up */ } 

... 

try { 
    // oh noes 

} catch (MyException me) { 
    cleanup(); 
} catch (AnotherException ae) { 
    cleanup(); 
} 

Mancanza di manutenzione!

+2

Tranne che ora non hai accesso alle cose che si trovano all'interno del chiamante. Se questo è ciò che deve essere pulito, tu lo proverai. E se passi la roba incasinata, allora stai codificando la lista delle cose da sistemare - e se questa lista cambia in seguito, devi cambiare ogni luogo che la usa. E ti mancherà uno. – cHao

+0

Oh, e questa funzione 'cleanup' dovrebbe * sicuramente * essere' privata', se insisti per averlo. – cHao

+0

@cHao Mentre ture e infine è sicuramente più bello, se ti manca un posto il codice non verrà compilato, quindi è ancora meno male – Voo

0

Si potrebbe provare avvolgendo due strati di gestori di eccezioni, e rigenerare l'eccezione dopo aver fatto la gestione comune:

try { 
     try { 
      // your code goes here 

     } catch (Throwable t) { 
      // do common exception handling for any exception 
      throw t; 
     }  

    } catch (NullPointerException nx) { 
     // handle NPE 
    } catch (Throwable t) { 
     // handle any other exception 
    } 

Non sono sicuro che mi piace questa soluzione però ... si sente come un po 'di mod. Probabilmente preferirei vedere l'eccezione gestita esplicitamente in ogni istanza, anche se questo significa ripetere una chiamata a qualche tipo di funzione di pulizia condivisa.

Problemi correlati