So erstellen Sie einen Java-Iterator, der IOException auslöst

8

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%     
Antonio 09.10.2012, 13:52
quelle

11 Antworten

6

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.

    
user949300 16.10.2012, 19:40
quelle
6

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

%Vor%

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 :

verarbeitet %Vor%

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.

    
artbristol 13.10.2012 15:19
quelle
3

Next () wirft Ссылка , Sie können eine schreiben Benutzerdefinierte Ausnahmeklasse, die diese Ausnahme abfängt und dann die IOException auslöst.

    
sheidaei 09.10.2012 14:06
quelle
1

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.

    
Mangesh Jogade 13.10.2012 12:42
quelle
1

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.

    
Carlos Gavidia 13.10.2012 13:03
quelle
1

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.

    
quelle
1

Hier ist mein Beitrag und unten der Stapel.

Es ist nicht wirklich was du willst, aber es ist nahe.

%Vor%

Und die Ausnahme Stack-Ablaufverfolgung:

%Vor%     
Aubin 13.10.2012 15:33
quelle
0

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.

    
Jason 16.10.2012 19:15
quelle
0

Es gibt noch einen weiteren Ansatz für dieses Problem. Die Hauptidee besteht darin, NoSuchElementException zu erweitern:

%Vor%

Der Nachteil ist, dass NoSuchElementException erweitert RuntimeException .

    
Antonio 16.10.2012 21:37
quelle
-1

checked exception ist nur ein Syntaxlimit

code unten von lombok Ссылка

Sie werden

erhalten

Ausnahme im Thread "main" java.io.IOException     bei B.main (B.java.19)

%Vor%     
farmer1992 09.10.2012 14:33
quelle
-1

Ich habe einen Beispielcode auf ideone gepostet. Die Grundidee besteht darin, eine benutzerdefinierte RuntimeException-Klasse IOIteratorException zu erstellen, die nur eine IOException als Ursache ausnimmt. Dann kannst du Code wie diesen schreiben

%Vor%     
emory 15.10.2012 11:56
quelle

Tags und Links