Perché è sconsigliato lanciare un'eccezione generica (java.lang.Exception), quando di solito è sufficiente per gestire la maggior parte dei fallimenti condizionali all'interno di un metodo? Capisco che se un metodo può lanciare più tipi di eccezioni, allora lanciare sottoclassi specifiche di un'eccezione potrebbe chiarire la gestione di un bit, ma in un caso di fail/fail generale penso che Exception sia più che adeguato.Eccezione generica di lancio scoraggiata?
risposta
Il problema è che Exception
è anche la superclasse di RuntimeException
, che comprende alcune cose che non dovrebbero essere prese in quanto indica un problema con la programmazione, piuttosto che un eccezionale condizione che deriva dal contesto. In circostanze normali, non si desidera rilevare BufferOverflowException o UnsupportedOperationException. Inoltre, il lancio di tipi di eccezioni separati fornisce al codice di chiamata il controllo su come gestirne ciascuno. Boilerplate è ridotto in Java 7 con la nuova funzionalità multi-catch.
Questo è un altro problema importante, +1. –
@MarkPeters Anche se raramente dico "mai", dal momento che anche il peggior anti-pattern può essere la risposta giusta in situazioni contorte, è meglio fare attenzione con le eccezioni. A volte devono essere gestiti da un codice che non hai scritto e finirai col perdere le astrazioni in tutto il negozio. Poi, naturalmente, c'è chi cattura "Throwable" come se non fosse un grosso problema: D –
+1 - Punto davvero ottimo. – DerMike
Se si lanciano eccezioni più specifiche, ciò non impedisce a nessun codice chiamante di occuparsi di tutti in un blocco di cattura Exception
. Essere più specifici è più documentare su quale tipo di errori si verificano, rendendo più facile per i programmatori gestirli separatamente.
Inoltre, lanciando "Exception" si sta dicendo ai chiamanti del codice che non possono escludere alcuna classe di eccezione. Un IOException
potrebbero verificarsi, come potrebbe un NumberFormatException
, ecc
In genere si desidera sapere cosa è successo nella propria app e si rilevano solo eccezioni specifiche e si lascia che il programma fallisca (o diventi più alto nell'ordine di esecuzione) quando si ottiene l'eccezione che non si targetizza in modo specifico. Catching Exception li catturerà tutti e in alcuni casi non sapresti che il tuo programma sta fallendo.
Come sempre: dipende.
Penso che ci sia una differenza tra API che esponi agli altri. Potrebbe vivere per qualche tempo. In tal caso non si conosce ciò che il chiamante ritiene migliore per il suo caso.
D'altra parte c'è sempre un codice che usi internamente solo per te stesso. Di quanto potrebbe essere sufficiente lanciare un'eccezione generica. Ma ricorda, potresti voler cambiare qualche gestione delle eccezioni in seguito. Ciò sarà più difficile quando tutti i casi di errore verranno distrutti insieme.
Dittos to GH. Avrei usato "eccezione puntatore nullo" e "eccezione memoria insufficiente" come esempi più ovvi del tipo di eccezioni che probabilmente non guardi nello stesso blocco con le eccezioni di vera applicazione.
Vorrei anche aggiungere che vale la pena fare un piccolo sforzo per l'espandibilità futura. Se si lanciano eccezioni generiche dappertutto e in seguito si decide che è necessario rilevare alcune eccezioni e non altre, può essere un grosso problema tornare indietro e modificarle tutte. Ma se crei le eccezioni di cui hai bisogno mentre vai avanti, non è un grosso problema. La creazione di una nuova classe di eccezioni che accetta solo un costruttore con un messaggio prende, quali, 5 linee di codice? È un buon investimento per il futuro.
Come molte cose in programmazione, è una questione di quanto lontano si va. Generalmente creo una "BadInputException" piuttosto generica in quasi tutti i progetti su cui lavoro, e lancio questo in qualsiasi momento in cui gli utenti immettono i criteri di convalida dei fallimenti. Quindi posso solo prendere BadInputException e lanciare il messaggio sullo schermo. Se creo una classe complessa che genera eccezioni per dati incoerenti e quel genere di cose, di solito creo una classe di eccezioni per questo. Come se creo una classe "TalkToDatabase", creerò un "TalkToDatabaseException". (Forse più di questo se ci sono più tipi di eccezioni che so di voler prendere, ma almeno quella.)
E a proposito, non so se ci stai pensando, ma sconsiglio vivamente di esaminare il testo di un messaggio di errore per determinare il tipo di errore. Ho visto programmi in cui si gettano eccezioni generici in tutto il luogo, e poi in blocchi catch hanno codice come
// Very bad idea! Don't do this!
catch (Exception ex)
{
if (ex.getMessage().equals("Invalid foo"))
... handle bad foo ...
else if (ex.getMessage().equals("Plugh is over maximum"))
... handle bad plugh ...
... etc ...
}
Sarebbe molto meglio fare solo eccezioni separate per questi casi. Non solo l'elaborazione sarà molto più efficiente, ma supponiamo che tu faccia quanto sopra e che qualcuno arrivi più tardi e decida di cambiare il messaggio in "Foo is invalid"? Il programma verrà comunque compilato, ma non funzionerà correttamente.
- 1. Lancio di una nuova eccezione durante il lancio di una vecchia eccezione
- 2. boost mutex lancio (dispari?) Eccezione
- 3. Eccezione C++ - lancio di una stringa
- 4. BluetoothSocket.connect() eccezione di lancio "lettura non riuscita"
- 5. eccezione di lancio dal costruttore in C++
- 6. android.media.audiofx.Visualizer eccezione di lancio ogni altra volta
- 7. Enumerazione dei file Eccezione di lancio
- 8. Eccezione di lancio fuori intervallo in C++
- 9. Eccezione di lancio in Foreach/Map Block
- 10. Eccezione di lancio ed è messaggi
- 11. Eccezione di lancio e notifica all'utente
- 12. Eccezione di lancio nel metodo principale
- 13. log4net lancio di Eccezione di sicurezza nell'applicazione Web ASP.Net MVC
- 14. Qual è la differenza tra lancio e lancio con arg di eccezione rilevata?
- 15. VisualCollection eccezione di lancio fuori intervallo, associata alla collezione Observable
- 16. Reattivo nativo con Genymontion di lancio concomitante Eccezione
- 17. Differenza tra ritorno Future.failed (Eccezione) e lancio di un'eccezione
- 18. Eccezione di lancio quando la matrice è fuori limite
- 19. PowerShell: creazione e lancio di una nuova eccezione
- 20. Eccezione lancio lancio a molla su valore If-Modified-Since non valido
- 21. Mongo lancio "Nome elemento 'nome' non è valido' eccezione
- 22. Avviso per connessione abbandonata - Con tomcat 7 lancio Eccezione PooledConnection
- 23. Lancio SQL nativo Eccezione nome colonna non valido
- 24. Come fermare XMLReader lancio non valido XML Character Eccezione
- 25. Errore di lancio di SwitchCompat
- 26. Eccezioni di lancio da ContinueWith
- 27. Eccezione di lancio e restituzione di valore nullo con istruzione switch
- 28. Jackson errori di lancio
- 29. due attività di lancio
- 30. Lancio di eccezioni
possibile duplicazione di [Best practice per la gestione delle eccezioni in Java o C#] (http://stackoverflow.com/questions/409563/best-practices-for-exception-management-in-java-or-c-sharp) –