2009-07-08 15 views
321

In C#, posso utilizzare l'istruzione throw; per rigenerare un'eccezione, mantenendo la traccia dello stack:rethrowing eccezioni in Java senza perdere lo stack trace

try 
{ 
    ... 
} 
catch (Exception e) 
{ 
    if (e is FooException) 
    throw; 
} 

C'è qualcosa di simile in Java (che doesn' t perdere la traccia dello stack originale)?

+3

Perché pensi che perde lo stacktrace originale? L'unico modo per perderlo quando si lancia la nuova SomeOtherException e si dimentica di assegnare la causa root nel costruttore o in initCause(). – akarnokd

+3

Credo che questo sia il modo in cui il codice si comporta in .Net, ma non sono più positivo. Potrebbe valere la pena di cercarlo da qualche parte o eseguire un piccolo test. – ripper234

+9

I 'Throwable's non vengono modificati gettandoli. Per aggiornare la traccia dello stack devi chiamare 'fillInStackTrace()'. Convenientemente questo metodo viene chiamato nel costruttore di un 'Throwable'. – Robert

risposta

424
catch (WhateverException e) { 
    throw e; 
} 

sarà semplicemente rigenerare l'eccezione hai preso (ovviamente il metodo che circonda deve permettere questo tramite la sua firma, ecc). L'eccezione manterrà la traccia dello stack originale.

+3

Ciao, InterruptedException e dà un messaggio Exception non gestito quando aggiungo la linea di lancio. Non così se lo sostituisco con la più ampia eccezione e. Come dovrebbe essere fatto correttamente? –

+1

@James, ho appena osservato che il messaggio scompare se si aggiunge "getta XxxException" nella dichiarazione di funzione. – shiouming

+2

Nel compilatore Java 7 per tale rethrow è più intelligente. Ora funziona bene con specifiche eccezioni "getta" nel metodo di contenimento. –

23

in Java è quasi lo stesso:

try 
{ 
    ... 
} 
catch (Exception e) 
{ 
    if (e instanceof FooException) 
    throw e; 
} 
+0

Doesn ' t cambia/perde la traccia dello stack originale? – ripper234

+4

No, a patto che non istanziate un nuovo oggetto Exception, lo stacktrace rimane lo stesso. – Mnementh

+23

Vorrei aggiungere una cattura specifica per FooException – dfa

13

In Java, si limita a generare l'eccezione che è stata rilevata, quindi throw e anziché solo throw. Java mantiene la traccia dello stack.

76

io preferirei:

try 
{ 
    ... 
} 
catch (FooException fe){ 
    throw fe; 
} 
catch (Exception e) 
{ 
    ... 
} 
+4

Decisamente adatto in Java per catturare eccezioni specifiche rispetto al generico e controllare istanza di +1 – amischiefr

+2

Questo modello funziona bene per RuntimeExceptions. –

+0

E lascia che la speranza FooException sia deselezionata o dichiarata nella parte di proiezione del metodo di inclusione. Le eccezioni C# sono deselezionate e possono essere ridistribuite liberamente – akarnokd

5

qualcosa di simile

try 
{ 
    ... 
} 
catch (FooException e) 
{ 
    throw e; 
} 
catch (Exception e) 
{ 
    ... 
} 
58

Si può anche avvolgere l'eccezione in un altro e tenere la traccia dello stack originale passando l'eccezione come Throwable come il parametro causa:

try 
{ 
    ... 
} 
catch (Exception e) 
{ 
    throw new YourOwnException(e); 
} 
+3

Vorrei anche consigliarvi di aggiungere un messaggio a fianco, usando 'lancia nuova YourOwnException (" Errore durante il tentativo di .... ", e);' – Julien

5
public int read(byte[] a) throws IOException { 
    try { 
     return in.read(a); 
    } catch (final Throwable t) { 
     /* can do something here, like in=null; */ 
     throw t; 
    } 
} 

Questo è un esempio concreto in cui il metodo genera uno IOException. final significa che t può contenere solo un'eccezione generata dal blocco try. Materiale di lettura aggiuntivo può essere trovato here e here.

+1

Non deve essere definitivo. Vedi http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html e http://stackoverflow.com/a/6889301/131160 –

0

La traccia di stack è prerivata se si avvolge l'escetion in un'altra eccezione (per fornire maggiori informazioni) o se si ripassa l'escetion catturata.

try{ ... }catch (FooException e){ throw new BarException("Some usefull info", e); }

Problemi correlati