2014-07-03 16 views
11

Se ho un metodo che genera un'eccezione incontrollato, ad esempio:Esiste un vantaggio nel dichiarare che un metodo genera un'eccezione non controllata?

void doSomething(int i) { 
    if (i < 0) throw new IllegalArgumentException("Too small"); 
    // ... 
} 

c'è alcun vantaggio per dichiarare esplicitamente che il metodo genera l'eccezione, cioè

void doSomething(int i) throws IllegalArgumentException { 
    if (i < 0) throw new IllegalArgumentException("Too small"); 
    // ... 
} 

rispetto a (o in Oltre al) descrive il comportamento in javadoc:

/** 
* This method does something useful. 
* @param i some input value 
* @throws IllegalArgumentException if {@code i < 0} 
*/ 
void doSomething(int i) { 
    if (i < 0) throw new IllegalArgumentException("Too small"); 
    // ... 
} 

I motivi per cui avrei rivendicazione non è utile avere la throws sono:

  • throws fornisce alcuna informazione per quanto riguarda le circostanze in cui viene generata l'eccezione, solo che potrebbe essere gettati;
  • Poiché si tratta di un'eccezione non controllata, non sono obbligato a gestire l'eccezione nel codice di chiamata. Saprò davvero che potrebbe essere lanciato se vado a dare un'occhiata all'implementazione di doSomething;
  • Il corpo di doSomething potrebbe richiamare il codice che genera altri tipi di eccezione non controllata; affermando che "questo metodo genera IllegalArgumentException" sembra che stia raccontando solo parte della storia, potenzialmente;
  • Se il metodo non è definitivo, può essere sovrascritto in modo tale che la nuova implementazione venga dichiarata per generare eccezioni non controllate aggiuntive; non sai quale implementazione stai invocando.

I motivi per cui vorrei sostengono che sarebbe utile avere la throws sono:

  • Si sta segnalando un problema che si potrebbe ragionevolmente aspettarsi di incontrare quando si richiama il metodo.

Insomma, penso che throws non è necessaria, ma una descrizione javadoc tramite @throws è utile. Sarei interessato a conoscere l'opinione degli altri su questo.

+1

Speriamo che questo thread sia di aiuto sul problema - [Gestione delle eccezioni secondo gli standard di codifica Java] (http: // StackOverflow.it/q/10344173/1057230) –

risposta

5

Quando si affermi che un metodo throws un'eccezione si sta dicendo al chiamante:

si hanno due scelte:

  1. ridichiarare se stessi come gettare la stessa eccezione.
  2. Cattura l'eccezione e gestiscila.

Nel caso 1 può ricordare all'utente di realizzare un finally - che potrebbe essere un bonus.

Nel caso 2 si concentra la mente sull'eccezione che potrebbe anche essere un bonus.

Se si nasconde questa possibilità, nessuno dei suddetti promemoria viene visualizzato dall'utente.

Per me uno può inutilmente ingombrare il proprio codice mentre l'altro lo mantiene dolce e semplice. Tuttavia, uno incoraggia a concentrarsi su potenziali problemi mentre l'altro può lasciarti in beata ignoranza.

Linea di fondo - Chiedetevi come irritante sarà di dichiarare l'eccezione come gettata (ad esempio, si dovrebbe dichiarare throws NullPointerException -?! NO) ed è questa irritazione equilibrato per il rialzo di focalizzare gli utenti mente su catch, finally e throws .

6

Se l'utente della propria API non può vedere il codice sorgente, non vedrebbe i commenti javadoc. Ecco perché la proposizione della clausola throws potrebbe essere utile.

Inoltre, è più semplice per alcuni programmatori determinare rapidamente l'eccezione dalla firma del metodo piuttosto che vedere cosa c'è all'interno di javadoc.

Ma in generale, penso che sia più utile elencare le eccezioni non controllate solo in javadocs, perché se ci sono entrambe le eccezioni controllate e non controllate nella clausola throws, la situazione potrebbe confondere. Non è possibile determinare il tipo di eccezione senza compilatore o senza esaminare ogni firma di classe di eccezione.

Tuttavia eccezioni non controllate indicano che la situazione è critica e non può essere risolta dal programma in fase di esecuzione. Se si utilizzano le eccezioni non controllate per scopo di eccezioni controllate (si presuppone che la situazione possa essere risolta) ma per qualche motivo non si desidera che il compilatore imponga l'eccezione, quindi si consiglia di inserire l'eccezione nella clausola throws.

+0

Si fa un punto ragionevole, ma aiuta solo a conoscere le eccezioni generate direttamente nel mio metodo - supponiamo che 'doSomething 'invochi un metodo che lancia' NullPointerException'. Ci sono due circostanze: 1) dichiarano che il metodo 'lancia NullPointerException' - dovrei dichiarare che il mio metodo genera anche quel tipo di eccezione? Devo dichiarare che potrei lanciare tutte le eccezioni non controllate passate in transito nel codice chiamato? 2) Se non dichiarano che il metodo 'genera NPE', posso sapere che lancia NPE senza accedere al loro codice? –

+0

1) Se ti aspetti che NPE non sia una situazione critica, cioè è una parte della tua logica aziendale (non raccomando tale comportamento) - piuttosto che includerla in 'getta' 2) No non puoi – Nailgun

+0

Penso se intendi utilizzare un'API senza la relativa documentazione associata, stai comunque percorrendo una linea pericolosa. Sono a favore solo delle indicazioni Javadoc. –

0

eccezioni sono utilizzati per la segnalazione di 3 tipi di problemi:

  • Problemi con il JVM e ambiente di runtime di basso livello.
  • Rilevati errori logici (bug).
  • Problemi di runtime impossibili per il programmatore di prevedere prima di provare un'operazione.

I primi due tipi potrebbe accadere in qualsiasi momento e non v'è essenzialmente alcun buon modo di trattare con loro. Quindi non ha senso catturarli e quindi non ha senso documentarli dichiarandoli in una clausola throws. Il terzo tipo è il tipo che vuoi che i clienti sappiano e gestiscano. Per quelli, si vuole documentare chiaramente che l'eccezione potrebbe essere lanciata, con l'implicazione che il codice chiamante deve essere preparato per gestire l'eccezione catturandolo o diffondendolo correttamente. È possibile utilizzare la clausola throws per farlo.

Ora, a me sembra chiaro che i progettisti del linguaggio Java intendevano le eccezioni controllate e solo le eccezioni controllate, da utilizzare per quel terzo tipo. Se fosse sempre così, la semplice risposta alla tua domanda sarebbe, no, non ha dichiarato eccezioni non controllate nella clausola throws.

Ma c'è una complicazione. È now quite common (reso popolare da Spring) per evitare eccezioni controllate per quel terzo tipo e utilizzare eccezioni non controllate in quasi tutti i casi. Se si sta programmando in tale stile, potrebbe essere utile utilizzare la clausola throws per dichiarare le eccezioni non controllate.