2012-10-16 14 views
7

Ho alcune domande sulla gestione delle eccezioni in Java. Ho letto un po 'su di esso e ho ottenuto alcune linee guida contraddittorie.Buone pratiche per la gestione delle eccezioni Java

Best Practices for Exception Handling

Andiamo attraverso l'articolo citato:

Essa afferma che si dovrebbe generalmente evitare l'uso di eccezioni controllate se "Codice cliente non può fare nulla". Ma cosa significa esattamente? La visualizzazione del messaggio di errore nella GUI è un motivo sufficiente per far ribollire l'eccezione verificata? Ma costringerebbe il programmatore GUI a ricordare di catturare RuntimeExceptions e i loro discendenti per visualizzare potenziali informazioni di errore.

La seconda vista presentata in questo articolo è che si dovrebbe evitare di inventare le proprie classi di eccezione a meno che non intenda implementare alcuni campi/metodi doganali in esse. Generalmente non sono d'accordo con questo, la mia pratica oggi è stata esattamente l'opposto: ho avvolto le eccezioni nella mia propria struttura di eccezione in obiettivi riflessi realizzati dalle classi che scrivo, anche se estendono Eccezione senza aggiungere nuovi metodi. Penso che aiuti a gestirli in modo più flessibile negli strati più alti quando vengono lanciati, inoltre è generalmente più chiaro e comprensibile per il programmatore che utilizzerà queste classi.

Ho implementato qualche codice oggi 'nuovo modo' presentato nell'articolo lanciando RuntimeException qua e là, quindi lascio analizzare Sonar. Per confondermi ancora di più, Sonar ha contrassegnato le mie RuntimeExceptions come errori principali con un messaggio come "Evita di lanciare eccezioni di tipo root, wrap'em nei tuoi tipi".

Quindi sembra piuttosto controverso, cosa ne pensi?

Ho anche sentito da uno dei leader della tecnologia oggi che solo il wrapping delle eccezioni è negativo, "perché è un'operazione davvero costosa per JVM". Per me, dall'altra parte lanciare SQLExceptions o IOException ovunque sembra un po 'di incapsulamento.

Quindi qual è la tua attitudine generale alle domande che ho presentato qui?

  1. Quando per avvolgere eccezioni nei miei propri tipi, quando non dovrei farlo?

  2. Dov'è quel punto di 'cliente non può fare nulla di questo, lanciare un'eccezione di runtime? '

  3. E i problemi di prestazioni?

+0

Sfortunatamente questo non è costruttivo per SO come da FAQ. Potresti voler provare programmers.stackexchange.com - detto questo, compra 'Effective Java' di Joshua Bloch. Chiunque seriamente su Java dovrebbe possedere una copia. –

+0

Effettuerei sicuramente la migrazione a Programmers.SE se potessi. C'è stato un tempo in cui potevamo farlo? O ho solo sempre atteso con ansia questa volta? –

+0

https://today.java.net/pub/a/today/2006/04/06/exception-handling-antipatterns.html è una bella lista di buone pratiche – bla

risposta

2

sembra che il tuo tech-lead, come spesso, è sfuggito il suo ruolo di sviluppatore perché non era bravo a farlo.

miei consigli sarebbe:

  • preferiscono le eccezioni di runtime sopra eccezioni controllate, soprattutto se non sei l'unico cliente della vostra API. L'utilizzo di un'eccezione controllata forza ogni client a gestire l'eccezione, anche se non può fare nulla al riguardo. Se questo è veramente ciò che vuoi fare (ad es.costringendo il chiamante a gestirlo), quindi un'eccezione controllata è ciò che si desidera.
  • se l'unica cosa che il client può fare quando si verifica un'eccezione è visualizzare un messaggio di errore più o meno generico come "oops, qualcosa di brutto è successo, riprovare o tornare alla pagina di benvenuto", quindi utilizzare sicuramente le eccezioni di runtime. La maggior parte dei framework di presentazione fornisce un modo per utilizzare un gestore di errori generico.
  • usa decisamente le eccezioni collegate al tuo livello di astrazione. Il lancio di una SQLException da un servizio di alto livello non è adeguato. Utilizzare i tipi di eccezione esistenti quando sono appropriati (come IllegalArgumentException per segnalare un argomento non valido). Altrimenti, avvolgere l'eccezione di basso livello in un tipo di eccezione appropriato di livello superiore. Ciò che è costoso è gettare un'eccezione. Se avvolge un altro o no non importa molto. E dovrebbe succedere solo eccezionalmente comunque.
+0

Ma per quanto ne so, le richieste di avvolgimento rilanciano passando 'vecchia' eccezione come parametro costruttore all'eccezione 'nuova'. Non è il costo di prendere e lanciare ancora il 200% del costo iniziale? –

+3

lanciare un'eccezione è più costoso di un 'se', ma non è un tale maiale da prestazione. Trascurabile rispetto a qualsiasi chiamata inter-processo o operazione IO. Prima esegui bene, quindi ottimizza solo se necessario, e se hai rilevato che questa è stata la causa del problema di prestazioni. Non lo sarà. –

+0

200% di poche istruzioni è ancora poche istruzioni. –