2015-05-08 12 views
7

Ho cercato di trovare una risposta a questa domanda ma non ho ottenuto alcuna spiegazione soddisfacente. Ecco alcuni retroscena:Java7 gestione di eccezioni multiple

Java 7 ci consente di intercettare più eccezioni in un unico blocco di catch purché tali eccezioni provengano da una gerarchia differente. Ad esempio:

try { 
    // some code 

} catch(SQLException | FileNotFoundException e) { 
    e.printStackTrace(); 
} catch(Exception e) { 
    e.printStackTrace(); 
} 

Ma se eccezioni sono della stessa gerarchia dobbiamo usare più blocchi catch come:

try { 
    // some code 
} catch(FileNotFoundException e) { 
    e.printStackTrace(); 
} catch(IOException e) { 
    e.printStackTrace(); 
} 

Ma se provo a scrivere codice come sotto compilatore si lamenta che "L'eccezione FileNotFoundException è già catturato dalla alternativa IOException "

try { 
    // some code 
} catch(FileNotFoundException | IOException e) { // compiler error 
    e.printStackTrace(); 
} 

Ora la mia domanda è: perché il compilatore segnala un errore in quest'ultimo caso, non è vero cifra che FileNotFoundException è un caso speciale di IOException? Ciò farebbe risparmiare la duplicazione del codice quando la mia logica di gestione delle eccezioni è la stessa.

+0

Se si sta gestendo 'IOException', non è necessario utilizzare lo stesso blocco di gestione per' FileNotFoundException' –

risposta

13

Perché compilatore segnala un errore in quest'ultimo caso, non può che accorgersi che FileNotFoundException è caso particolare di IOException?

Perché è una sottoclasse di IOException. In altre parole, la parte "FileNotFoundException |" è ridondante.

Il motivo per cui il codice qui sotto è ok ...

} catch(FileNotFoundException e) { 
    ... 
} catch(IOException e) { 
    ... 
} 

... è perché qui gli argomenti IOException clausola: se un SocketException è gettato per esempio, si passerà alla dalla parte FileNotFoundException, e impigliarsi nella clausola IOException.

0

Quando si rileva un'eccezione, si ordinano le clausole di cattura dal più specifico al più generale.

Si consideri il seguente gerarchia:

class MyException extends Exception {} 

class MySubException extends MyException {} 

Se una parte del vostro codice genera un MyException un'altra parte getta MySubException si deve prendere MySubException prima.

catch(MySubException e){ 

} catch(MyException e){ 

} 

È come utilizzare l'operatore instanceof.

Se si verifica se un'istanza di MySubException è un'istanza di MyException, il risultato sarà true.

mse = new MySubException(); 

if(mse instanceof MyException){ 
    println("MyException"); 
} else if(mse instanceof MySubException){ 
    println("MySubException"); 
} 

Questo pezzo di codice non potrà mai stampare "MySubException".

mse = new MySubException(); 

if(mse instanceof MySubException){ 
    println("MySubException"); 
} else if(mse instanceof MyException){ 
    println("MyException"); 
} 

Questo sarebbe l'ordine corretto.

0

È perché FileNotFoundException estende IOException, come hai detto della stessa gerarchia, non è possibile aggiungerli allo stesso blocco catch.