2012-01-24 13 views
4

いくつかの頻度では、ネットワーク接続によってバックアップされたIterator<Foo>を提供するAPIを作成しています。実装はネットワーク接続を開き、ストリームから情報を読み取り、その情報を非直列化してFooに送り、呼び出し元に渡します。残念ながら、いつもIOExceptionの可能性があり、ネットワーク接続を正常に終了する必要があります(発信者が最後のFooを読み取ったときに自動的に行うことができますが、それが起こらない場合はどうなりますか?)。ネットワーク接続でバックアップされたJavaイテレータ

Iteratorの実装で投げ、そして受け入れられたアドバイスは「未チェックRuntimeException秒でそれらをラップ」であることになるチェック例外に対処する方法についての質問のカップル(herehere)がすでにあります。一方、ネットワーク接続を閉じるために、Closeableを実装することができます。だから私たちは行儀例外チェックの呼び出し元に対するこのようなもので終わる:

Iterator<Foo> iter = null; 
try { 
    iter = getFooIterator(); 
    while(iter.hasNext()) { 
     Foo foo = iter.next(); 
     // do something with foo 
    } 
} 
catch(RuntimeException e) { 
    if(e.getCause() instanceof IOException) { 
     // do something with the IOException 
    } 
    else throw e; 
} 
finally { 
    if(iter instanceof Closeable) try { ((Closeable)iter).close(); } catch(IOException e) {} 
} 

そして、Iteratorを実装するために、このような素晴らしいアイデアのように思えました。より良い方法がありますか?

+0

Java 7で作業している場合は、「AutoCloseable」を使用してtryステートメントのリソースを開くことも考えられます。 'try(iter = getFooIterator();){...}'(イテレータは 'AutoCloseable'を実装する必要があります)。 – Thomas

+0

イテレータのメソッド( 'next()'や 'hasNext()'など)で接続を終了してから、例外をスローすることもできます。このようにして、イテレータのユーザはイテレータ(およびその基礎となる接続)を閉じることを心配する必要はなく、例外を処理するだけで済みます。 – Thomas

+0

私は大きなIteratorの人ではないことを認めなければなりません(私はコレクションと単純な配列を1トン使用します)。なぜ簡単なAPIになるコレクションではなく、これらの自由な質問を持つIteratorを返すのですか?あなたはコレクションを取り戻し、すべてが閉じられ、何らかの例外が発生する可能性があります。私は答えを知っていると思うが、質問したいと思う。 – user949300

答えて

1

IMO最初のステップは、実装またはアプリケーション固有の例外で包括し、汎用のRuntimeExceptionをキャッチしたり、根本原因をチェックする必要がなくなります。

私は、クローズ可能なチェックを避け、IOExceptionを覚えておくために、特定の実装を検討したいと思います。

NetworkIterator<Foo> iter = null; 
try { 
    iter = getFooIterator(); 
    while (iter.hasNext()) { 
     Foo foo = iter.next(); 
     // do something with foo 
    } 
} catch (NetworkIteratorExceptiom e) { 
    // do something with the IOException 
} finally { 
    iter.close(); 
} 

私はおそらくはない定型が離れて行く作るためにそれをする方法を与えるだろうが、私は誘惑されると思います。大まかに:

NetworkIterator<Foo> iter = new IteratorThang<Foo>() { 
    @Override public void each(Foo foo) { 
     // Do something with foo 
    } 
}; 
+0

良いアイデア。実際には、チェックされた例外をスローできる特定のIteratorに似ているのではなく、 'java.util.Iterator'を実装することさえ本当に利益があるのだろうかと思います。 'Iterator'には多くの消費者がいますか? –

+0

@ RobertTupelo-Schneckあらゆる種類のものがイテレータを消費します。 [Guavaの 'any'メソッド](http://stackoverflow.com/a/8991373/438992)のようなものを考えてください - これのような怠惰な繰り返しのための多くの用途があります。これは基本的には、実際に必要となるまでキャッシュを作成するまで、後の値を生成しない長い計算と同じです。数学ではなくネットワークからのものです。 –

関連する問題