Perché alcune API lanciano semplicemente l'eccezione?

5

Quest'anno ho iniziato a utilizzare diverse librerie di terze parti (tutte open source) e ho notato che alcune eccezioni lanciano in modo corretto (cioè dichiarando esattamente quali eccezioni controllate possono essere lanciate da un metodo nella firma del metodo), mentre altri dichiarano solo throws Exception , che generalmente rende più difficile catturarli e gestirli correttamente. Penso che esempi per i "buoni" siano le librerie di Apache (almeno quelle che uso come commons-cli ), gli esempi per quelli "cattivi" sono WEKA e il Simple Framework XML. (Tutti i miei esempi sono esempi Java perché uso principalmente Java, ma la mia domanda vale in generale.)

Quindi, un ovvio motivo per il comportamento "cattivo" è che è più facile / veloce da programmare e può sembrare più bello di un throws ThisException, ThatException, AnotherException . Ma questa è davvero una ragione per cui esiste?

Questo non riguarda Eccezioni selezionate / non selezionate . Riguarda la leggibilità e che devo fare i conti con un'eccezione che ha semplicemente il tipo Exception di base senza informazioni di chiarimento. Se fosse un'eccezione non controllata, forse sempre la stessa, sarei molto felice finché la documentazione chiarisse perché è successo. Inoltre, ad es. l'API Simple Framework utilizza eccezioni speciali all'interno, ma tutto ciò che viene propagato al livello più alto è "Exception".

Quali sono le ragioni di questo comportamento in generale?

    
posta GreenThor 30.11.2016 - 13:03
fonte

4 risposte

9

Non ci sono buone ragioni per farlo. E infatti dichiarare un metodo come throws Exception lo rende difficile da usare. Questo è coperto da questo "esempio" nell'albero della documentazione Java Language su StackOverflow:

La versione breve è che se dichiari un metodo come throws Exception , qualsiasi codice che chiama quel metodo deve o catch (Exception ...) o avere la propria clausola throws Exception . Se lo fai, le conseguenze sono le seguenti:

  • Hai annullato la capacità del compilatore di dirti quando non hai gestito le eccezioni controllate specifiche .

  • Qualcuno che legge il tuo codice API non ha un modo semplice per scoprire quali eccezioni controllate potrebbero essere effettivamente generate o propagate dal metodo.

risposta data 30.11.2016 - 13:43
fonte
3

I would be very happy as long as the documention clarifies why it happened. In addition, e.g. the Simple Framework API uses special exceptions inside, but all that is propagated to the top level is "Exception". What are the reasons for this behaviour in general?

Probabilmente perché qualunque sia stata l'eccezione sotto il cappuccio, non puoi fare altro che registrarlo e passare o mostrarlo all'utente finale analisi della causa non riuscita: [eccezione tradotta / messaggio] . La tua applicazione non può fare qualcosa di specifico per l'eccezione specifica che è accaduta sotto il cofano, l'elaborazione xml fallita, la fine della storia, vedi messaggio & stack, è tutto ciò di cui hai bisogno.

Questo potrebbe essere racchiuso in una GenericSimpleFrameworkXmlException. Ti permette di avere più catture, ma per essere onesti, non ho quasi mai un altro problema che si limita a registrare e rethrow perché non c'è altro che posso fare.

modifica: non ho un log / rethrow su ogni livello della mia applicazione, solo dove penso abbia senso, a volte mi rilancio o converti uno selezionato in uno deselezionato o nell'altro se Penso che questo sia ciò di cui ho bisogno .

Nel rarissimo caso in cui ho bisogno di una cattura specifica, ho solo diviso il codice in due try / catch block. Succede così raramente che non appesantisce nulla nella redabilità del codice nel suo insieme.

Personnaly in quasi tutti i casi, preferisco usare l'IllegalArgumentException, IllegalStateException ... con il messaggio giusto invece di creare il mio mazzo di eccezioni personalizzate per questo. Questo è più semplice, fa il lavoro, e non ho mal di testa su come nominare e organizzare l'albero per .. praticamente niente.

    
risposta data 30.11.2016 - 15:44
fonte
1

Eccezioni, beh, la gestione degli errori in generale è una cosa noiosa che molti sviluppatori non vogliono affrontare ... periodo.

Il semplice fatto che così tanti di noi vivono negando la possibilità di errore che potrebbe derivare dalla scrittura del codice è in realtà centrale nel dibattito Checked vs Unchecked. Stai riscontrando aspetti diversi dello stesso problema.

Quindi le eccezioni controllate sono fastidiose perché devi gestirle in qualche modo ad ogni chiamata lungo lo stack di chiamate. È vero, quindi la soluzione a questo problema è di lanciare Exception e farla finita, o come sempre più importante, dal momento che Java 8 è sufficiente avvolgerli in una RuntimeException e dimenticarsene.

Questo problema non è nuovo, prima delle eccezioni avevamo funzioni che restituivano un codice di errore. Eppure spesso ho letto codice in cui molto raramente questi codici di errore sono stati controllati in qualsiasi modo è diventato praticamente la norma.

Avere Eccezione come unico tipo in tutte le firme dei metodi è un periodo di desing delle API scadente, proprio come lanciare la stessa SQLException è stata una cattiva scelta da parte della gente che ci ha dato JDBC. Come minimo sai che il codice PU CAN generare un'eccezione ed essere pronto per questo, invece di non sapere nemmeno se le eccezioni possono essere lanciate.

    
risposta data 30.11.2016 - 17:03
fonte
1

Un motivo è dovuto al fatto che il framework in questione esegue richiami al codice fornito dall'utente e l'autore del framework non vuole limitare quali eccezioni è consentito al codice di callback, quindi aggiungono semplicemente throws Exception alle loro interfacce in per consentire ogni possibile implementazione. Devono quindi propagare questa eccezione all'interfaccia pubblica dei propri metodi, perché non conoscono le eccezioni che l'utente potrebbe lanciare e non possono gestirli internamente.

    
risposta data 30.11.2016 - 20:17
fonte

Leggi altre domande sui tag