Hai ragione.
Le eccezioni non selezionate vengono utilizzate per consentire al sistema di fallire rapidamente, il che è positivo. Dovresti indicare chiaramente qual è il tuo metodo per funzionare correttamente. In questo modo è possibile convalidare l'input solo una volta.
Per esempio:
/**
* @params operation - The operation to execute.
* @throws IllegalArgumentException if the operation is "exit"
*/
public final void execute( String operation ) {
if( "exit".equals(operation)){
throw new IllegalArgumentException("I told you not to...");
}
this.operation = operation;
.....
}
private void secretCode(){
// we perform the operation.
// at this point the opreation was validated already.
// so we don't worry that operation is "exit"
.....
}
Solo per fare un esempio. Il punto è che se il sistema si guasta rapidamente, allora saprai dove e perché ha fallito. Otterrai uno stacktrace come:
IllegalArgumentException: I told you not to use "exit"
at some.package.AClass.execute(Aclass.java:5)
at otherPackage.Otherlass.delegateTheWork(OtherClass.java:4569)
ar ......
E saprai cosa è successo. La OtherClass nel metodo "delegateTheWork" (alla riga 4569) ha chiamato la tua classe con il valore "exit", anche quando non dovrebbe ecc.
Altrimenti dovresti cospargere le convalide su tutto il codice e questo è soggetto a errori. Inoltre, a volte è difficile rintracciare ciò che è andato storto e potresti aspettarti ore di frustrante debug
La stessa cosa accade con NullPointerExceptions. Se si dispone di una classe di 700 righe con circa 15 metodi, che utilizza 30 attributi e nessuno di essi può essere nullo, invece di convalidare in ciascuno di questi metodi per nullabilità è possibile rendere tutti quegli attributi di sola lettura e convalidarli nel costruttore o metodo di fabbrica.
public static MyClass createInstane( Object data1, Object data2 /* etc */ ){
if( data1 == null ){ throw NullPointerException( "data1 cannot be null"); }
}
// the rest of the methods don't validate data1 anymore.
public void method1(){ // don't worry, nothing is null
....
}
public void method2(){ // don't worry, nothing is null
....
}
public void method3(){ // don't worry, nothing is null
....
}
Eccezioni controllate Sono utili quando il programmatore (tu o i tuoi colleghi) avete fatto tutto bene, convalidato l'input, eseguito test e tutto il codice è perfetto, ma il codice si collega a un servizio Web di terze parti che potrebbe non essere attivo (o un file che stavi utilizzando è stato eliminato da un altro processo esterno ecc.). Il servizio web potrebbe anche essere convalidato prima di tentare la connessione, ma durante il trasferimento dei dati qualcosa è andato storto.
In quello scenario non c'è niente che tu o i tuoi colleghi potete fare per aiutarlo. Ma devi comunque fare qualcosa e non lasciare che l'applicazione muoia e scompaia agli occhi dell'utente. Usi un'eccezione controllata per questo e gestisci l'eccezione, cosa puoi fare quando ciò accade ?, il più delle volte, solo per tentare di registrare l'errore, probabilmente salvare il tuo lavoro (il lavoro dell'app) e presentare un messaggio all'utente . (Il sito blabla non è attivo, riprovare più tardi, ecc.)
Se l'eccezione selezionata viene utilizzata in modo eccessivo (aggiungendo la "eccezione Eccezione" in tutte le firme dei metodi), il codice diventerà molto fragile, perché tutti ignoreranno quell'eccezione (perché è troppo generale) e la qualità del codice sarà seriamente compromessa.
Se usi eccessivamente l'eccezione non selezionata, accadrà qualcosa di simile. Gli utenti di quel codice non sanno se qualcosa potrebbe andare storto e apparirà un sacco di tentativi {...} catch (Throwable t).