4-5-3: Javaの配列について


・ Javaの配列を理解する上での一番のポイントは、 Javaの配列はクラスと非常に似た存在であるという事実です。 実際、システム内部での取り扱いにはほとんど違いがありません。 文法上で配列とクラスに記述の違いが存在するのは、 むしろプログラマへの配慮かもしれません。 Cで使われている記述方法に慣れている方には、 比較的理解しやすい形式になっています。
ただし JavaとC の配列の記述法は全く同じルールというわけではありません。 特に配列の初期化については、JavaとC では記述法が大きく異なります。 配列を初期化するために、 オブジェクトの生成の場合と同じように 「コンストラクタの呼び出し」が必要になるのです。 多くのプログラマが Javaに接して最初にまごつくのは、 次のような「普通の」配列の宣言が許されないことでしょう。


int data[100];

これはコンパイル時にエラーと見なされてしまいます。 正しくは次のように書かなければなりません。


int data[] = new int[100];

クラスのオブジェクトが配列になった場合も同様です。 この場合には「二重に」コンストラクタが呼び出されるように見えて、 確かに慣れるまではまぎらわしく思えるのも事実です。


Color colors[] = new Color[10];  // 10個の Colorのオブジェクトからなる配列の生成
for( int i; i<10; i++ ) {
     colors[i] = new Color( i*20, 0, 0 );  // 個々の Colorオブジェクトの生成
}

・ Javaの配列は、通常は実際に必要になった場所でサイズを指定するのが普通です。 その意味では使用方法は Cのポインタに近いとも言えます。 配列の変数が配列のデータの実体への参照を記憶する点も似ているでしょう。 ただし、 参照の値がアドレスのような物理的な意味を持っているわけではありませんし、 メモリーの確保や解放を直接指定する必要はありません。 メモリーの確保に相当するのが、上のような一種のコンストラクタを呼び出すことです。 メモリー領域が不要になったことは null の代入で明示することもできますが、 普通はブロックの処理を抜けて 自然に参照の変数が消滅するのにまかせておけば大丈夫です。 このような取り扱いは通常のクラスの場合と変わりません。
また、配列のデータの実体の寿命やメソッドへの引数の受け渡しや 返値として返す場合の考え方も全く同じです。 メソッドの呼び出しで配列を表す変数が受け渡されたり返される場合、 やりとりされるのは配列の参照です。 配列のコピーが作られて渡されることはありません。
また、どんな型の配列もすべて一種の publicなフィールドに相当する length という値を内部に持っています。 配列のサイズを知りたい時にはこのフィールドにアクセスすればいいわけです。 ここでもクラスとの共通点があることがわかると思います。


int data[] = new int[100];
int size = data.length;    //値 100 が得られる