In un quadro di eccezioni ben progettato, occorre fare una distinzione tra eccezioni che sono in una certa misura "previste" e quelle che non lo sono. Java tenta di utilizzare le eccezioni controllate e non controllate per questo. Secondo questo standard, IOException dovrebbe essere un'eccezione controllata.
Un problema fondamentale, tuttavia, è che spesso il codice verrà scritto con una (forse ragionevole) aspettativa che una certa eccezione non si verifichi e nulla può essere fatto utilmente per gestirlo se lo fa. Se un metodo viene dichiarato come lancio di una particolare eccezione verificata, Java consente al chiamante di ignorare l'eccezione se si dichiara di lanciare quell'eccezione, ma non c'è modo in cui un metodo o un blocco di codice possa specificare che certe eccezioni dai metodi chiamati siano non dovrebbe verificarsi. Un anti-modello comune è:
try
{
methodThatsDeclaredAsThrowingFooExceptionButWont()
}
catch FooException Ex
{
// Never going to happen
}
Il presupposto evidente è che, poiché il metodo non getterà FooException e l'unico motivo per il catch
c'è è quello di rendere il compilatore felice, non c'è alcun motivo per il catch
da fare nulla. Insidioso, perché se un FooException
viene lanciato, per qualsiasi motivo, non verrà rilevato.
Un'alternativa è per un metodo che chiama methodThatsDeclaredAsThrowingFooExceptionButWont per dichiararsi come throws FooException
o throws Exception
, ma anche questo non è proprio appropriato. Se un metodo che non è previsto per il lancio di un FooException
, lo stato del sistema è adatto per essere diverso da quello che ci si aspetterebbe quando viene lanciato un FooException
.
Ad esempio, si supponga di voler caricare un documento, ma la routine di caricamento del documento deve leggere alcune tabelle di traduzione non specifiche del documento che devono essere memorizzate in una posizione fissa; se il tentativo fallisce, avere il percolato fino al chiamante IOException
implicherebbe che si è verificato un problema nel caricare il documento che si sta caricando. Se la routine load-document non è preparata a gestire in modo ragionevole la possibilità che la routine load-translation-tables possa fallire, tale errore non dovrebbe percolarsi allo stesso modo di un IOException
che si è verificato durante il caricamento del documento.
Il rimedio appropriato non sarebbe per IOException
essere un'eccezione incontrollato, ma piuttosto per lì per essere un mezzo dichiarative attraverso il quale il codice potrebbe indicare che uno o più tipi di eccezioni controllate, non dovrebbe essere consentito di percolato di una certa blocco dai metodi chiamati in tal modo, ma dovrebbe invece essere racchiuso in qualche altro tipo di eccezione (ad es. RuntimeException).
Molte persone pensano che OGNI eccezione avrebbe dovuto essere senza controllo ... – leonbloy
Molte persone hanno bisogno di prendere in considerazione che le eccezioni hanno Vuoi sapere che potrebbe accadere. –
@ Thorbjørn: Dubito che sia una coincidenza che nessun'altra lingua abbia copiato il modello di eccezione chekced. È stato un esperimento interessante, suona bene in teoria, ma fa molto più male che bene nella pratica. –