2010-04-29 7 views
5

Lassen Sie uns sagen, dass ich die folgende Java-Schnittstelle, die ich nicht ändern kann:Die Java-Schnittstelle gibt keine Ausnahme aus. Wie man geprüfte Ausnahmen der Implementierung verwaltet?

public interface MyInterface { 
    public void doSomething(); 
} 

Und nun die Klasse der Umsetzung es so ist:

class MyImplementation implements MyInterface { 
    public void doSomething() { 
    try { 
     // read file 
    } catch (IOException e) { 
     // what to do? 
    } 
    } 
} 

ich nicht von nicht lesen erholen die Datei.

Eine Unterklasse von RuntimeException kann mir eindeutig helfen, aber ich bin nicht sicher, ob es das Richtige zu tun ist: vielleicht das Problem ist, dass diese Ausnahme würde dann nicht in der Klasse dokumentiert werden und ein Benutzer der Klasse bekommen würde Diese Ausnahme weiß nichts darüber, dies zu lösen.

Was kann ich tun?


Wir sind uns alle einig: die Schnittstelle ist fehlerhaft.

Lösung wählte ich

ich ein MyVeryOwnInterface entschieden schreiben schließlich, dass die MyRuntimeExceptionMyInterface und fügt als Teil der Signatur der fehlerhaften Methoden erweitert:

public interface MyVeryOwnInterface extends MyInterface { 
    public void doSomething() throws MyRuntimeException; 
} 
class MyImplementation implements MyVeryOwnInterface { 
    public void doSomething() throws MyRuntimeException { 
    try { 
     // read file 
    } catch (IOException e) { 
     throw new MyRuntimeException("Could not read the file", e); 
    } 
    } 
} 
+0

Siehe: http://www.javapractices.com/topic/TopicAction.do?Id=44 –

Antwort

8

Sie haben das Problem von leaky abstractions kennengelernt. Es gibt keine wirklich gute Lösung, und mit einem RuntimeException so ziemlich das einzige, was Sie tun können.

Dies ist auch ein Beispiel dafür, warum checked exceptions ein fehlgeschlagenes Konzept sind.

+0

Oder es ist ein Beispiel dafür, warum "doSomething" zu viele Verantwortlichkeiten hat. – CPerkins

+2

Ok, danke für das Prinzip der undichten Abstraktionen. Es ist jedoch das erste Mal in 10 Jahren Erfahrung in Java, dass ich auf dieses Problem stoße, das ist nicht, was ich ein "gescheitertes Konzept" nennen würde. –

+6

Natürlich sind geprüfte Ausnahmen kein "gescheitertes Konzept". Sie sind sehr nützlich. In diesem Fall liegt der Fehler beim Schnittstellen-Designer, nicht beim Sprachen-Designer. – DJClayworth

0

Ich glaube nicht, dass es ist etwas zu tun, außer throws IOException in der Schnittstelle zu deklarieren. Das ist einfach die Art von Java-Schnittstellen und geprüften Ausnahmen.

Sie könnten eine andere Methode in Ihrer Klasse haben (doSomethingDangerous), die die IOException auslöst. Von der doSomething -Implementierung, rufen Sie einfach doSomethingDangerous (in einem Versuch/Fang eingehüllt) und dann, wo immer Sie vorsichtig sein wollen über doingSomething Sie rufen doSomethingDangerous direkt.

2

Wenn Sie nicht wiederherstellen können, müssen Sie werfen und damit in eine RuntimeException oder einen Fehler umbrechen und das werfen.

public class Unchecked extends Error { 

    private final Exception source; 

    public Unchecked(Exception source) { 
     this.source = source; 
    } 

    public String toString() { 
     return "Unchecked Exception, Caused by: " + source; 
    } 

    public Exception getSource() { 
     return source; 
    } 

    public static Unchecked wrap(Exception cause) { 
     return new Unchecked(cause); 
    } 
} 
0

Ich würde vorschlagen,

throw new RuntimeException("while reading file " + fileName + "...", e); 

Ist hier nicht das Problem, dass die Schnittstelle erwartet keine Probleme überhaupt?

(und Sie möchten vielleicht Ihre eigene OurCompanyDomainException erstellen erweitert RuntimeException, um es im Code auf der anderen Seite der Schnittstelle zu unterscheiden).

3

Ich würde eine werfen und ein Problem an den Betreuer der Schnittstelle einreichen.

1

Offensichtlich ist der Interface-Designer schuld, weil er nicht in Betracht zieht, dass doSomething() fehlschlagen könnte. Im Idealfall sollte er entweder IOException ausgelöst haben (wenn er den Verdacht hatte, dass IO invovled wäre) oder eine SomethingException (aktiviert), mit der Sie Ihre IOException umbrechen könnten.

Wenn Ihnen der Schnittstellen-Designer zur Verfügung steht, sprechen Sie mit ihnen und fragen Sie, was im Falle eines Fehlers erwartet wird. Vielleicht können sie die Schnittstelle ändern: oder vielleicht ist es akzeptabel, stillschweigend gemäß dem Vertrag der Schnittstelle zu versagen.

Wenn all dies fehlschlägt, werden Sie auf eine Auswahl von stillschweigendem Misserfolg beschränkt (möglicherweise Aufzeichnung, aber nicht auf das Problem reagierend) oder eine RuntimeException werfen, die den Prozess beenden kann.

Verwandte Themen