• ベストアンサー

配列数を超えてアクセスしたときの処理

 「名簿クラス Meibo」 を自作しようと思っています。 人の名前の配列 person[0]~person[max-1]をフィールド変数に持ちます。 このとき、Meibo から名前を取り出すメソッド  getMemberName(int id) {   return person[id];  } では、「id が max を超えていないか」をチェックした方が良いと思います。 C言語を使っていた時は  getMemberName(int id) {   assert (id < max);   return person[id];  } のように、assert 関数でチェックをしていました。 しかし、調べてみると、java では assert のサポートはバージョン1.4からのようです。 java を使う人たちは、通常こういうときにどうしてきたのでしょうか? (assert 関数を自作する?)

質問者が選んだベストアンサー

  • ベストアンサー
  • kazsharp
  • ベストアンサー率37% (16/43)
回答No.5

「Javaを使う人たちは、通常こういうときどうしてきたのでしょうか?」と聞かれているので、なるべく正確に答えると、「何もしない」となると思います。 通常、Javaでは配列の境界チェックは行わず getMemberName(int id) { return person[id]; } とするのが一般的です。 ここで質問者さんに知ってほしいことが2つあります。 1つはなぜ「何もしない」のかということですが、Javaでは配列の境界チェックはVM側がやってくれるので、配列の範囲を超えたアクセスをすると「ArrayIndexOutOfBoundsException」がスローされます。それに対しC言語では配列のサイズを超えていても「配列があるものとして」アクセスするため、万が一配列のサイズを超えたインデックスを指定してまうと不正なメモリアクセスを行い重大な問題になりかねません。それでassertによって厳しいチェックを行っているのでしょう。 そしてもう一つはJavaで1.4からサポートされているassertは通常、「実行時にはオフ」にします。これはassertは開発中にバグを発見するために主に用いられ、「プログラムが誤っている」状態だと判断するものだと言えるからです。それに対し「例外」は実行時のエラー、プログラムが予期せぬ処理を実行しようとしたときに使われるものだ言えます。この2つを区別しておくことは重要です。 ちなみに、どうしても境界チェックを行いたい場合、私なら if (isAvailableID(id)) { String name = getMemberName(id); } というように、呼び出し元のほうでチェックするようにします。ついでにisAvailableIDメソッドは public boolean isAvailableID(int ID) { reutrn 0 <= ID && ID <= person.length-1; } といった感じでしょうか。

white-tiger
質問者

補足

非常に納得できました。 ありがとうございます!

すると、全ての回答が全文表示されます。

その他の回答 (4)

  • LancerVII
  • ベストアンサー率51% (1060/2054)
回答No.4

よくよく見たらすごい勘違い・・・ 配列の最大数はわかってますね。 呼び出し側の処理でmaxを超えてたらnullを返すとか 空白を返すとかエラーを投げるとか用途によってわけるかもしれません。

white-tiger
質問者

補足

みなさん、ありがとうございます。みなさんのご回答によると ●何もしなくても、ArrayIndexOutOfBoundsException というエラーを java が出してくれる Cより随分便利ですね。 ●だから、呼び出し側で java が出すエラー(か自作のエラー)を拾って処理すればよい。 ●もしくは、return null をする というところが中心でしょうか。 最初は、呼び出し側ではなく Meibo の方で処理が完結すればよいと思っていました。しかし、よく考えたら、呼び出し側も Meibo のエラー処理を知っておく必要があるのですね。

すると、全ての回答が全文表示されます。
  • LancerVII
  • ベストアンサー率51% (1060/2054)
回答No.3

こんにちは。 person.length で配列の要素数がintで返ってくるのでそれで比較してます。 try~catchでArrayIndexOutOfBoundsExceptionを拾うなんてことも 可能ですね。

すると、全ての回答が全文表示されます。
  • kgi03334
  • ベストアンサー率26% (24/90)
回答No.2

2通りあります。 1. if文を使い、id < max のときのみreturnするようにする。 2. getMemberNameを呼ぶところで、try~catchをする。

すると、全ての回答が全文表示されます。
  • anmochi
  • ベストアンサー率65% (1332/2045)
回答No.1

> java を使う人たちは、通常こういうときにどうしてきたのでしょうか?  例外をスローするのが一般的じゃないかなぁ。まぁこれは私の流儀なので一般ではないかも知れない。 getMemberName(int id) {   if(id < max)     throw new Exception("配列の範囲を超えています");   return person[id]; }

すると、全ての回答が全文表示されます。

関連するQ&A