Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

NoSuchElementExceptionについて

Iteratorのnextメソッドによる繰り返し処理で、それ以上要素がない場合、NoSuchElementExceptionがスローされると思いますが、nullが返ってくる時代がありましたでしょうか?

ご存知の方、情報提供をよろしくお願いします。

11

回答

8979

閲覧

11件の回答

評価

0

「何らかの値が返る」のはIteratorではなくIteratorをimplementsしたクラスである、という点は置いておくとして。

ある特定の実装においては、nullが返る=列挙の完了であっても別に差し支えはない。
それは単にクラスの機能の問題。

しかし、不特定のIterator実装においてnullを列挙の完了と見なすことはできない。
nullは正常値としても取り得る値である。

評価

0

Iterator は インタフェースなので
現在でもそういう実装は可能である。

AbstractList.Itr に関してはエレメントが存在しない場合 NoSuchElementException が投げられるようになっていたはず。

評価

0

実装だけでなくドキュメントも仕様と考えるべきです。「インターフェースは実装を伴わないから、それ以上要素がない場合にnullを返すことは可能」と考えるのは誤りです。javadocでは明確にNoSuchElementExceptionが投げられると規定されていますので。

よって、「それ以上要素がない場合」つまり、hasNextメソッドがfalseを返す状況下でnextメソッドがNoSuchElementExceptionを投げずにnullを返すというのは、そのIterator実装クラスの誤り・不具合であると言えます。

ただし、「それ以上要素がない場合」に該当しないのであればnextメソッドがnullを返しても構いません。たとえば要素の最後に番兵としてのnullを配置するといったことは認められます。この場合は、番兵であるnullが取り出されるまでhasNextメソッドはtrueを返す必要がありますから「それ以上要素がない場合」には該当しないことになります。番兵であるnullが返された後は、hasNextメソッドはfalseを返し、nextメソッドはNoSuchElementExceptionを投げる必要があります。

評価

0

みなさまご回答ありがとうございます。

返事が遅く申し訳ないです。

それぞれの方の意見、どれも勉強になり、納得のいくものでした。

確かにインタフェースって実装次第ですね。
肝心なところが記憶から抜けてました。

(表現が合っているかわかりませんが)JDK内にあるクラス内に限定した場合、JDK1.2や1.3の時代にnullを返していたことがあれば情報をいただきたく、質問させてもらいました。

評価

0

>そのIterator実装クラスの誤り・不具合であると
言えます。
publicなクラスでなければ、その局所的な使用に
おいて使いやすいように実装すればいい。
厳密な意味にこだわって使い勝手を犠牲にするの
は、道具に使われていることになる。

hasNext()とnext()の間を開けたくない場合、そう
いう実装になるかもしれない(マルチスレッ
ド)。
自前のIteratorを定義すればいい話だけど。

評価

0

> 自前のIteratorを定義すればいい話だけど。

その通り。自前定義せずにJavaのIteratorをインプリメントするのであれば、Iteratorのドキュメントも含めた仕様に準拠して正しく実装すべき。

局所的な使用だからといって標準に沿わなくていいという考え方には賛同できません。そのような標準に沿わないコードが存在しているだけで、コードレビューが難しくなります。自分の生産性だけでなく周りのことも考えたほうが良いでしょう。

評価

0

要求に沿うことで全体の生産性が下がることもあ
るんだよ。
世の中、全てか理想的にはいかないもの。

評価

0

$さん個人が泥臭い糞コードを書くのは別にかまいませんが、Iteratorインターフェースの実装クラスについて「nullが返る=列挙の完了であっても別に差し支えはない。」と公言するのはやめていただきたいです。害悪なので。

よろしくお願いします。

評価

0

$氏が言っているのは現実的という意味では最もだと思うが理想は@氏の言っている通りに出来ればに越したことは無いがそれに対する制約等も特にないため所詮、理想でしかない。
※現実に全ての人間にそれを押し付けるのは不可能だし実際の現場においても似たようなことは多々あるのが現状。

インターフェースはあくまで実装を制約させるだけであって処理まで制約するものではない。

そういう意味ではnextなどが必ずしも次の要素を指す必要はないし、たとえば3回までは同じ要素を返すようにして以降は次の要素にってのもありだ。

評価

0

「差し支えない」について。
「null=終了はあり得るか」という話だったので、「Iterator I/Fとしては違うが、そう実装されているクラスが現実にあるかもしれない、実装できないものではない」という感じ。
「制約なんぞ気にしないでいい、読む側使う側に全く影響はない」と言うつもりではなかったが、そう誤解させていたら失礼。


私自身はそうしたくない(nullは返さない)し、今までそんなことはしてない…はず。
ただし、他者、とくに赤の他人が既に実装したものについて、敢えて何か言おうとは思わないということ。
何らか保険は欲しい(JavaDocに明示する、ソースに「この文書を参照しろ」etc.)としても、それ以上は期待しない。


とはいえ、#next()でnullを返さないと「使う側がうまくいかない」ケースは、正直 先に挙げたことくらいしか思い付かないな…。



>、JDK1.2や1.3の時代にnullを返していたことがあれば
これに答えられてないな。
バージョンアップしてもソースをそのまま使えることが前提なJavaの標準ライブラリにおいて、I/F自体にそんな重大な変更を加えることはまずないように思う…とくにnullは正常値なんだし。
一部の標準クラスがそう実装されていた可能性は否定できないにしても(@氏が言うとおり明らかに不具合だ)、IteratorをhasNext()→next()で使うことは大前提なので、露見する可能性は低かった気がする。

評価

0

>JDK1.2や1.3の時代にnullを返していたことがあれば

Oracle Java archive でぐぐると いろんなJavaのversion をダウンロードできるから自分でしらべろ。

見ることも勉強。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。