2017-06-01 5 views
2

Ich habe zwei Klassen von java.lang.Exception erben. Beide haben eine Methode mit der gleichen Signatur void a(){...}. Sie können beide in einen Codeblock geworfen werden. Wenn ich das tue:Nicht definierte Methode in Mehrfach-Ausnahme-Catch

catch (SubException1 | SubException2 e) 
    { 
     e.a(); 
    } 

Dann wird es nicht kompilieren, weil Methode a() nicht zu Exception gehören. Ist es ein Java-Sprachfehler? Wie sollte ich meinen Code richtig gestalten, um Code-Redundanz zu vermeiden?

+0

Die Signatur keine Rolle spielt, ist es die gleiche Methode einer gemeinsamen Oberklasse? Ist 'a' in einer gemeinsamen Oberklasse von' SubException1' und 'SubException2' definiert? – luk2302

+1

Sie können Redundanz eliminieren, indem Sie ihnen einen gemeinsamen Vorfahren geben, der die Methode 'void a()' verordnet hat. Dann können Sie den Vorfahren fangen und 'e.a()' anrufen – Ishnark

+0

Wenn Sie Multicatch verwenden, ist der tatsächliche Typ der lokalen Ausnahmevariable der am nächsten liegende allgemeine Supertyp, der in Ihrem Fall so aussieht, als wäre er 'Exception'. Es spielt also keine Rolle, dass "SubException1" 'a()' hat. Sie können dies lösen, indem Sie einen gemeinsamen Supertyp mit 'a()' auf beiden Methoden haben, wie bereits vorgeschlagen. –

Antwort

3

Wenn Sie mehrere Ausnahmetypen in einer einzigen catch-Anweisung erfassen, ist der abgeleitete Typ der erfassten Ausnahme der größte gemeinsame Nenner dieser Klassen. In Ihrem Fall ist der größte gemeinsame Nenner Exception, der nicht über die Methode void a() verfügt. Um es zugänglich für den catch-Block machen Sie sie entweder zu einer gemeinsamen Basisklasse extrahieren könnten, oder (wohl) elegante, definieren sie in einer Schnittstelle, die beiden Klassen implementieren:

public interface SomeExceptionInterface { 
    void a(); 
} 

public class SomeException extends Exception implements SomeExceptionInterface { 
    // Implementation... 
} 

public class SomeException2 extends Exception implements SomeExceptionInterface { 
    // Implementation... 
} 
2

Wenn Sie auf eine Methode namens a() zugreifen müssen, benötigen Sie einen Typ, der diese Methode bereitstellt. Eine einfache Lösung könnte sein:

public class AbstractSubException extends Exception { 
    public abstract void a(); 
} 

public class SubException1 extends AbstractSubException { 
    @Override public void a() { ... } 
} 

public class SubException2 extends AbstractSubException { 
    @Override public void a() { ... } 
} 

Dann können Sie die Art und Weise fangen Sie getan haben oder (etwas einfacher):

catch (AbstractSubException e) { 
    e.a(); 
} 

Vielleicht ist der Code für die Methode a das gleiche in allen Unterklassen ist. Dann können Sie es konkretisieren und den Code in die Elternklasse einfügen.

Verwandte Themen