2

私が次のものを持っているとしましょう(ideone):

x = [1,2,3]
y = x.iterator();

println y.next();
println y.next();
println y.next();
println y.next();

これは以下を出力します:

1
2
3
Caught: java.util.NoSuchElementException
java.util.NoSuchElementException
    at java_util_Iterator$next.call(Unknown Source)
    at prog.run(prog.groovy:7)

予想通り。

しかし、 に変更x = [1,2,3]してみましょうx = 1..3。コードは次のようになります ( ideone ):

x = 1..3
y = x.iterator();

println y.next();
println y.next();
println y.next();
println y.next();

出力が得られます。

1
2
3
null

また、例外はスローされません。これはなぜですか?[1,2,3] と 1..3 を反復処理するときに異なる動作をするのは本当に予想外です。そのような行為はiteratorさんの契約に違反しているようです。

この動作を修正する方法はありますか?また、そのような修正によって他の問題が発生することはありますか?

4

3 に答える 3

1

編集:より明確にしましょう:

これは、Iterator クラスの正しい使用法です。

x = 1..3
y = x.iterator();

while(y.hasNext()) {
    println y.next();
}

NoSuchElement例外は未チェック (AKA ランタイム) 例外です。チェックされていないのは、例外に頼らなくても完全に回避できるはずのものだからです。これは、たとえば、IOExceptionチェックされ、通常の使用中に発生する可能性がはるかに高い s とは異なります。

ドキュメントでは明示的に述べられていませんが、上記のように Iterator が正しく使用されているときにnext()メソッドが a をスローするのを見るのは、アイテムを持つ非同期のマルチスレッド環境に変更可能なコレクションがある場合だけですを使用して呼び出してからアイテムにアクセスするまでの間に削除されます。NoSuchElementExceptionhasNextnext

クラスは変更できないため、Rangeそのような状況が発生する可能性はありません。

項目の機能または状態を判断するために、チェックされていない例外に依存しないでください。

ですから、契約が破られたとは思いません。イテレータを使用するための契約はhasNextbeforeを使用することnextであり、Range クラスの Iterator は、間違って使用されているという理由だけで例外をスローする必要はありません。

于 2013-07-09T04:57:36.150 に答える