2015-05-08 5 views
7

Ich habe versucht, eine Antwort auf diese Frage zu finden, erhielt aber keine zufriedenstellende Erklärung. Hier ist ein Hintergrund:Java7 multiple Ausnahmebehandlung

Java 7 ermöglicht es uns, mehrere Ausnahmen in einem einzigen catch-Block zu fangen, sofern diese Ausnahmen von verschiedenen Hierarchie sind. ZB:

try { 
    // some code 

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

Aber wenn Ausnahmen von der gleichen Hierarchie sind, müssen wir mehrere catch-Blöcke wie verwenden:

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

Aber wenn ich versuche, Code zu schreiben, wie unten Compiler beschwert sich, dass „Die Ausnahme FileNotFoundException bereits durch die alternative IOException "gefangen

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

Nun meine Frage: Warum Compiler einen Fehler in letzten Fall berichtet, kann es nicht Figur heraus, dass FileNotFoundException Sonderfall von IOException ist? Dies würde die Code-Duplizierung speichern, wenn meine Ausnahmebehandlungslogik dieselbe ist.

+0

Wenn Sie 'IOException' verarbeiten, müssen Sie nicht den gleichen Handler-Block für' FileNotFoundException' verwenden –

Antwort

13

Warum Compiler einen Fehler in letzten Fall berichtet, kann es nicht herausfinden, dass FileNotFoundException ist Sonderfall IOException?

Da FileNotFoundException eine Unterklasse von IOException ist. Mit anderen Worten, der Teil "FileNotFoundException |" ist redundant.

Der Grund, warum der Code unten ist ok ...

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

... ist, weil hier die IOException Klausel Fragen: Wird ein SocketException zum Beispiel geworfen wird, es der durch den FileNotFoundException Teil passieren wird, und erwischt werden in der IOException Klausel.

0

Wenn Sie eine Ausnahme abfangen, müssen Sie Ihre Fangklauseln vom spezifischsten zum allgemeinsten sortieren.

Betrachten Sie das folgende Hierachie:

class MyException extends Exception {} 

class MySubException extends MyException {} 

Wenn ein Teil des Codes wirft MyException einen ein anderer Teil wirft MySubException Sie zuerst fangen MySubException haben.

catch(MySubException e){ 

} catch(MyException e){ 

} 

Es ist die gleiche Sache wie die Verwendung des instanceof-Operators.

Wenn Sie testen, ob eine Instanz von MySubException eine Instanz von MyException ist, wird das Ergebnis wahr sein.

mse = new MySubException(); 

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

Dieser Codeabschnitt wird nie "MySubException" drucken.

mse = new MySubException(); 

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

Dies wäre die richtige Reihenfolge.

0

Da FileNotFoundException IOException ausdehnt, können Sie sie nicht demselben catch-Block hinzufügen.