2013-03-21 11 views
5

Si supponga che questo pezzo di codice è in 20 posti e sempre la stessaintercettare le eccezioni separati o utilizzare instanceof - Java 6

try { 
    // do something 
} catch (FirstException e) { 
    // log it 
} catch (SecondException e) { 
    // log it 
} 

Non sarebbe meglio usare qualcosa come questo o instanceof non è buona soluzione?

try { 
    // do something 
} catch(Exception e) { 
    logException(e); 
} 

void logException(Exception e) { 
    if (e instanceof FirstException) { 
     // log it 
    } else if (e instanceof SecondException) { 
     // log it differently 
    } else { 
     // do something with other exception 
    } 
} 

L'unica cosa che ho davvero odio la soluzione è la cattura di Exception che non è il modo migliore definitelly ... C'è un modo migliore?

+0

Vorrei utilizzare il primo approccio e chiamare logException per tutte le eccezioni rilevate. – Thihara

+0

Cosa accadrebbe se si lanciava 'FileNotFoundException !!! – Azodious

+0

Rilevare separatamente ogni eccezione ha senso solo quando si intende eseguire un'elaborazione diversa per ciascuna. Nelle applicazioni del mondo reale, questo è raramente il caso. L'approccio fattibile è quello di catturare tutti usando la superclasse 'Exception' o' Throwable' se gli errori di runtime sono un problema serio e ** li registrano correttamente in modo da avere senso allo sviluppatore dove e cosa è successo realmente. – Vrushank

risposta

8
  1. In Java 7, utilizzare catch (FirstException1 | SecondException | ...)
  2. Ci può essere niente di sbagliato con catch (Exception e) — si vuole effettuare il login tutti eccezioni, non è vero? Vorrei infatti consigliare catch (Throwable t) perché OutOfMemoryError s e StackOverflowError s vogliono anche essere registrati.

Un consiglio da molti anni di esperienza con le eccezioni di registrazione è di registrarli tutti allo stesso modo. Il messaggio di eccezione è sufficiente come testo leggibile dall'utente e ciò di cui lo sviluppatore ha realmente bisogno per il debug è la traccia dello stack.

Basta essere attenti a una cosa: mai prendere eccezioni troppo presto: li cattura in un unico luogo per l'intera applicazione, il cosiddetto barriera eccezione — è al livello in cui si entra e esce da un'unità di lavoro.

Se eccezioni controllate si stanno dando problemi al livello inferiore, avvolgerli in RuntimeException:

try { 
    ... 
} 
catch (RuntimeException e) {throw e;} 
catch (Exception e) {throw new RuntimeException(e);} 

Solo se si sa con precisione e in anticipo che c'è un'eccezione che ha significato a livello di business per l'applicazione, e non interrompe l'unità di lavoro corrente, ma reindirizza il flusso, è opportuno rilevare tale eccezione a un livello inferiore. In pratica tali eccezioni sono rare rispetto alla totalità di tutte le possibili eccezioni generate dal codice dell'applicazione.

+2

Non sta prendendo Throwable come il più grande male di tutti? Perché non voglio cogliere tutte le eccezioni ... solo le due – user219882

+0

Solo se le prendi troppo presto --- come spiego nella risposta modificata. –

+0

Grazie - non sapevo che potresti trovare un'eccezione a | b in java 7 (che ultimamente funziona principalmente in Obj-C). . . suggerimento a portata di mano –

1

Il primo approccio è decisamente migliore. In genere è una cattiva pratica catturare Exception perché in questo caso si cattura anche RuntimeException s.

1

Ex è pulito e ottima soluzione se devi solo registrare le eccezioni.

Altrimenti il ​​primo approccio è migliore.

1

Nel libro "Refactoring to Patterns" uno dei refactoring comuni è "replace instanceof with polymorphism" - in altre parole ogni volta che si usa instanceof, si consideri se il polymporphism funzionerebbe di fatto meglio. . .

Detto questo, per questa particolare domanda viene in mente la filosofia di Spring di sostituire eccezioni controllate con eccezioni di runtime (scusate il gioco di parole).

L'idea è che le eccezioni controllate possono essere sovrautilizzate - l'eccezione è qualcosa che potrebbe essere recuperato da? Se sì, ok. . . se no, lascia che si propaghi lungo la catena.È possibile effettuare questa operazione:

  • Rilanciare. . . (Ma meglio ancora)
  • avvolgerla in un RuntimeException

Creare un aspetto di registrazione:

Un'altra cosa da considerare è che se si ha bisogno di registrare queste eccezioni al proprio questo il punto in cui si verificano piuttosto che farli propagare sulla catena, e che si verificano in 20 luoghi diversi, quindi sono una preoccupazione trasversale. . . Si potrebbe avere il metodo normale solo rilanciare l'eccezione e quindi scrivere un aspetto per catturarli e registrarli. . . . di nuovo usando Spring lo rende facile.

Problemi correlati