2015-08-13 10 views
12

Perché throw outerE; genera un errore di compilazione? So che throw e; non dovrebbe generare un errore di compilazione a causa del precise rethrow feature.Perché una di queste eccezioni riconfigurate crea un errore del compilatore?

Sono la stessa Exception oggetto, ma uno è scoped all'interno del blocco catch è ambito unico e uno al di fuori del blocco try-catch.

Non dovrebbe nessuno di questi generare un errore del compilatore? O, almeno, si comportano allo stesso modo?

static void preciseRethrowTest() 
{ 
    Exception outerE; 
    try 
    { 

    } 
    catch (Exception e) 
    { 
     outerE = e; 

     // Compilation error here. Unhandled exception type Exception 
     // throw outerE; 

     throw e; // No compiler error 
    } 
} 

Sto usando Java 1.8.0_51. (Precise rethrow è introdotto in Java 7)

risposta

6

Il tuo metodo non ha dichiarazioni throws.

Il compilatore ora è abbastanza intelligente da determinare che il blocco try non può generare eccezioni controllate. Pertanto, tutte le eccezioni rilevate e vincolate al parametro Exception nel blocco catch devono essere deselezionate. Poiché sono deselezionati, puoi ripeterli a tuo piacimento (e non richiedono una dichiarazione throws).

Qui, si sta tentando di riassegnare

outerE = e; 
// Compilation error here. Unhandled exception type Exception 
// throw outerE; 

e rigenerare l'eccezione attraverso una variabile diversa. Il compilatore non si spinge così lontano per capire quale sia il valore in outerE. Può essere l'eccezione in te catturato o può essere qualcos'altro. Il compilatore gioca sul sicuro e ti impedisce di farlo.

consideri il codice come

if (Math.random() < 0.5) 
    outerE = e; 
else 
    outerE = new IOException("nope"); 
throw outerE; 

Non c'è alcun modo per il compilatore per sapere se il valore Exception memorizzato nel outerE è l'eccezione incontrollato hai preso o qualche altro, potenzialmente controllato, eccetto che è stato assegnato da qualche altra parte.

1

Il problema è che il blocco catch non può essere raggiunto da eccezioni controllate; il compilatore è abbastanza intelligente per rendersene conto.

Considerate questo:

public class RethrowTest { 
    static void preciseRethrowTest() { 
    Exception outerE; 
    try { 
     throw new Exception(); 
    } catch (Exception e) { 
     outerE = e; 

     // Compilation error here. Unhandled exception type Exception 
     // throw outerE; 

     throw e; // Now a compiler error *is* generated. 
    } 
    } 
} 

Questo fa lanciare un errore del compilatore, perché il codice è raggiungibile con un'eccezione controllata ora.