Come gestire le eccezioni controllate che non possono essere mai lanciate

32

Esempio:

foobar = new InputStreamReader(p.getInputStream(), "ISO-8859-1");

Poiché la codifica è hardcoded e corretta, la funzione di costruzione non getterà mai l'UnsupportedEncodingException dichiarata nella specifica (a meno che l'implementazione di java non sia interrotta, nel qual caso sono comunque persa). Ad ogni modo, Java mi obbliga ad affrontare comunque quell'eccezione.

Attualmente, sembra che

try {
    foobar = new InputStreamReader(p.getInputStream(), "ISO-8859-1");
}
catch(UnsupportedEncodingException e) { /* won't ever happen */ }

Qualche idea su come migliorarla?

    
posta user281377 29.11.2011 - 10:17
fonte

5 risposte

26

La mia abitudine è, solo per essere al sicuro, di mettere un assert nel blocco catch. Qualcuno potrebbe cambiare il contenuto del blocco try in un secondo momento e vuoi sapere se il codice non funziona?

    
risposta data 29.11.2011 - 10:23
fonte
33

Se mi fosse stato dato un centesimo per ogni volta che ho visto un log / errore, "Questo non dovrebbe mai accadere", avrei ... beh, due centesimi. Ma ancora ...

I blocchi di cattura vuoti fanno fremere il mio ragno e la maggior parte degli strumenti di analisi del codice si lamentano. Eviterei a tutti i costi di lasciarli vuoti. Certo, ora sai che l'errore non può mai accadere, ma tra un anno qualcuno sostituirà la ricerca globale di "ISO-8859-1" e all'improvviso potresti avere un bug estremamente difficile da trovare.

Il suggerimento assert false è buono, ma poiché le asserzioni può essere disabilitato in fase di esecuzione, non sono garantiti. Userei invece RuntimeException . Quelli non dovranno essere catturati chiamando le classi e se mai si verifichino si avrà una traccia di stack per fornire informazioni complete.

    
risposta data 29.11.2011 - 12:09
fonte
26

L'ho sempre fatto in questo modo:

try {
    foobar = new InputStreamReader(p.getInputStream(), "ISO-8859-1");
} catch(UnsupportedEncodingException e) {
    throw new AssertionError(e);
}

Può essere un po 'prolisso (Java è ...), ma almeno otterrai un errore di asserzione quando accade l'impossibile.

Se l'implementazione Java è interrotta, ti consigliamo di ottenere il messaggio di errore il più possibile, il più rapidamente possibile, invece di ignorare l'impossibile. E anche se l'implementazione Java non è interrotta, qualcuno potrebbe aver cambiato il tuo codice in "UTF8" (oops - dovrebbe essere stato "UTF-8" ?).

Questo dovrebbe essere stato un'eccezione di runtime in primo luogo. JDK è pieno di questo tipo di scelte sbagliate.

    
risposta data 29.11.2011 - 12:23
fonte
3

Se sei l'unico sviluppatore che vedrà mai questo codice, direi che va bene, ma se non lo sei, lo tratterei come una possibilità reale o almeno cambierò "non accadrà mai "commenta qualcosa di più utile.

    
risposta data 29.11.2011 - 10:27
fonte
3

La parte di queste eccezioni che mi infastidisce di più è che danneggia la copertura del mio codice.

Quando diventerò compulsivo riguardo alla copertura, rilascerò la prova / cattura che "non può mai accadere" (... o solo se sto usando una JVM mutante che in qualche modo ha dimenticato di includere "US-ASCII ") in una classe e un metodo che incapsula quello try / catch e sostituisce l'eccezione verificata in uno dei modi menzionati qui (di solito lanciando un'eccezione non controllata con un messaggio snide).

Quindi la copertura del mio codice subisce un duro colpo nella classe di utilità, ma non in tutti i riferimenti a quell'operazione sparsi nel mio codice.

A volte mi prendo del tempo per fare il rollup di operazioni simili in una classe che ha in realtà una semantica coerente. Ma dato che è abbastanza ovvio per i miei compagni quello che succede, di solito lo terrò il più semplice che posso e amp; non preoccuparti tanto del miglior design possibile.

Tuttavia, come commento citato, Guava & altre biblioteche hanno modi per mitigare questo dolore, ma questa è fondamentalmente la stessa strategia. Sposta il fastidio fuori scena in modo che il tuo codice principale non subisca il colpo di copertura.

    
risposta data 05.01.2015 - 16:09
fonte

Leggi altre domande sui tag