Ich möchte einen Iterator implementieren, der Objekte von der Festplatte / dem Netzwerk abruft.
%Vor% Das Problem besteht jedoch darin, dass hasNext()
und next()
Methoden der Methode verwendet werden Iterator -Objekt erlaubt nicht, IOException
zu werfen. Gibt es eine andere Standardschnittstelle, die dieses Problem umgeht?
Gewünschter Code ist:
%Vor%Es ist nicht genau das, was Sie wollen, aber überlegen Sie:
Dies passiert über ein Netzwerk, daher kann es langsam sein. Sie sollten wahrscheinlich ein Future
(oder ähnlich) verwenden.
Anstatt also RemoteIterator<E>
, wo next()
ein E zurückgibt, verwenden Sie
RemoteIterator<Future<E>>
, wobei ein Future<E>
zurückgegeben wird.
In der Methode Future.get()
können Sie jede IOException
in eine ExecutionException
umbrechen.
Nicht perfekt, aber Future.get()
impliziert, dass die Dinge langsam sein können. Außerdem wirft eine geprüfte Ausnahme , was andere Programmierer dazu bringt, was passiert, und die natürliche Antwort ist,% co_de aufzurufen %. Dies vermeidet die meisten "WTF" Aspekte.
Leider können Sie das nicht tun. Deklarierte Ausnahmen sind Teil der Signatur einer Methode, während Sie sie z. B. einschränken können.
%Vor%Sie können keine neuen throws-Klauseln einführen oder den deklarierten erweitern.
Iterator
ist eine grundlegende Java-Schnittstelle, die von enhanced for verwendet wird. Selbst wenn Sie irgendwie tun könnten, was Sie wollten, müsste der Compiler das wissen
erfordert, dass das checked IOException
abgefangen oder ausgelöst wird.
Es ist eine Frage der Meinung, aber ich denke, Sie sollten eine benutzerdefinierte Unterklasse von RuntimeException
verwenden und Ihre Schnittstelle sorgfältig dokumentieren. Überprüfte Ausnahmen werden in modernen Frameworks vermieden, z. Frühling, wegen der damit verbundenen Probleme.
Bearbeiten : Geborgt und angepasst aus der Antwort von user949300 können Sie das zurückgegebene Objekt z. B. in
umbrechen %Vor% Geben Sie dann Iterator<RemoteObject<T>>
zurück und erzwingen Sie, dass der Aufrufer die IOException
beim Entpacken mit get
:
In diesem Fall müssen Sie Iterator
nicht verlängern, es kann direkt verwendet werden. In der Tat können Sie Collection
verwenden, falls zutreffend.
Ich würde eher vorschlagen, dass die Methode getRemoteIterator () idealerweise eine IOException auslösen sollte, da das Abrufen von Objekten innerhalb der Methode stattfinden wird.
Iterator ist ein bekanntes Designmuster . Wenn der SDK-Iterator nicht Ihren aktuellen Anforderungen entspricht, können Sie einen Iterator selbst erstellen.
Ich finde eine schöne Erklärung und einen Beispielcode in dieser Site . Sie können diesen Code als Referenz verwenden und Ihre eigene Implementierung der Iterator-Schnittstelle durchführen, die Sie benötigen.
Das Grundproblem besteht darin, dass Sie eine geprüfte Ausnahme über eine API senden können, die dafür nicht vorgesehen ist.
Der einzige legitime Weg, um dies ohne schwarze Magie zum Laufen zu bringen, ist das Umbrechen mit nicht aktivierten Ausnahmen. Das einfachste ist RuntimeException:
%Vor% Sie können RuntimeException im aufrufenden Code abfangen und sich die Methode getCause()
ansehen.
Wenn Sie explizit feststellen müssen, dass dies Ihre Ausnahme ist, dann sollten Sie in Erwägung ziehen, FooBarDomainException extends RuntimeException
zu erstellen und die Konstruktoren zu implementieren, die Sie an super(...,e)
delegieren müssen. Sie können dann stattdessen FooBarException abfangen und getCause()
wie oben behandeln.
Ich rate dir davon ab, Magie dafür zu benutzen. Wenn Magie bricht, tendiert sie dazu, auf sehr nicht offensichtliche Weise zu sein, die schwer zu finden und zu beheben sind. Darüber hinaus wird es für andere schwieriger zu pflegen sein.
Ich schlage vor, dass Sie Ihre eigene Schnittstelle erstellen, die dem Iterator strukturell ähnlich ist, aber die hinzugefügte Schnittstellenbeschränkung hat, die Sie wollten.
Es klingt wie das, was Sie hier wirklich haben, ist ein Strom von Objekten. Ich würde diesen Weg gehen, mit der begleitenden Erwartung, dass Sie manchmal eine EOFException oder ähnliches bekommen.
checked exception ist nur ein Syntaxlimit
code unten von lombok Ссылка
Sie werden
erhaltenAusnahme im Thread "main" java.io.IOException bei B.main (B.java.19)
%Vor%Tags und Links java java-7 iterator ioexception