2009-07-08 19 views
12

A volte, devi semplicemente prendere Throwable, ad es. durante la scrittura di una coda di dispatcher che invia articoli generici e deve essere ripristinata da eventuali errori (detto registro dispatcher registra tutte le eccezioni rilevate, ma in silenzio, e quindi l'esecuzione continua su altri elementi).Best practice per la cattura di Throwable in Java

Una buona pratica a cui riesco a pensare è di ripetere sempre l'eccezione se si tratta di InterruptedException, perché questo significa che qualcuno ha interrotto il mio thread e vuole ucciderlo.

Un altro suggerimento (che proviene da un commento, non una risposta) è quello di rigenerare sempre ThreadDeath

Eventuali altre buone pratiche?

+2

Anche 'ThreadDeath' dovrebbe essere ripubblicato, ma non dovrebbe essere gettato in primo luogo. –

+0

Perché un commento, questo è solo il tipo di risposta che volevo? – ripper234

risposta

12

Probabilmente il più importante è, mai ingerire un'eccezione controllata. Con questo voglio dire non farlo:

try { 
    ... 
} catch (IOException e) { 
} 

a meno che questo è ciò che si intende. A volte le persone ingoiano le eccezioni controllate perché non sanno cosa fare con esse o non vogliono (o non possono) inquinare la loro interfaccia con clausole di "eccezioni".

Se non sai cosa fare con esso, fare questo:

try { 
    ... 
} catch (IOException e) { 
    throw new RuntimeException(e); 
} 

L'altra che viene in mente è quello di assicurarsi avete a che fare con le eccezioni. La lettura di un file dovrebbe essere simile a questa:

FileInputStream in = null; 
try { 
    in = new FileInputStream(new File("..."));; 
    // do stuff 
} catch (IOException e) { 
    // deal with it appropriately 
} finally { 
    if (in != null) try { in.close(); } catch (IOException e) { /* swallow this one */ } 
} 
+2

+1 sul mai ingoiare un'eccezione controllata, anche nel tuo 'primo passaggio'. troppo spesso queste cose vengono trascurate e infine sottoposte al controllo del codice sorgente. in caso di dubbio, stampa almeno la traccia dello stack. – akf

+0

Se non riesci a gestirlo e non riesci a ricrearlo, stampa almeno quella traccia dello stack! Una traccia dello stack nel registro è di grande aiuto nella diagnosi del problema. – starblue

+1

L'orrore delle eccezioni controllate ... cattura IOException solo per avvolgerlo in un'eccezione non controllata e NON fare nulla con esso? Naturalmente, questo è quello che devi fare in Java, a meno che tu non sappia davvero perché stai ricevendo l'Eccezione. –

2

Dipende da cosa si sta lavorando.

se si sta sviluppando un'API da utilizzare da qualcun altro, è meglio rilanciare l'eccezione o avvolgerla in un'eccezione personalizzata della propria e lanciare.

Considerando che se si sta sviluppando un'applicazione per utente finale è necessario gestire questa eccezione e fare ciò che è necessario.

1

Se si sta scrivendo una coda di dispatcher, al momento in cui l'eccezione ritorna a voi non ha senso fare nulla con esso se non registrarlo. La coda degli eventi Swing ha fondamentalmente quel tipo di comportamento.

In alternativa, è possibile fornire un hook per un "gestore di eccezioni non rilevate", simile a ThreadGroup. Tieni presente che il gestore potrebbe impiegare molto tempo e finire con il ritardare il dispatcher.

Per quanto riguarda InterruptedException: l'unica cosa che interessa è il ciclo di invio, che dovrebbe controllare uno stato esterno per vedere se deve interrompere l'elaborazione.

+0

Perché controllare uno stato esterno meglio di usare InterruptedException come meccanismo di segnalazione? – ripper234

+0

Poiché InterruptedException indica semplicemente che qualcuno ha chiamato interrupt() sul thread. Ci potrebbero essere diversi motivi per farlo, non solo per interrompere l'azione corrente. E se vuoi usare interrupt() per terminare il dispatcher, certamente non vuoi buttarlo; semplicemente ritorna da run() - a meno che, naturalmente, il tuo committente non sia l'unica cosa che fa il thread, ma anche lì, quasi certamente non vuoi buttare alla cieca. – kdgregory

2

Che dire di OutOfMemoryError (o forse della sua super classe VirtualMachineError)? Non riesco a immaginare che ci sia molto da fare dopo qualcosa di così serio.

+1

Se il thread che ha allocato molti oggetti capita di catturare l'errore OutOfMemoryError in un punto in cui l'allocata diventa obsoleta, la macchina virtuale può recuperare. Se gli oggetti sono ancora referenziati, allora sì, non c'è molto che puoi fare se non uscire o liberare alcuni oggetti. –

+0

Catch 'VirtualMachineError' è difficile perché il tuo programma è in uno stato indefinito: http://stackoverflow.com/questions/8728866/no-throw-virtualmachineerror-guarantees – Raedwald