配列の定義

Revised: Jan./1st/2004

前節で、コマンドライン引数と配列について紹介しました。本節では、配列の一般的な規則をまとめておきます。

配列は基本的に均質 (homogeneous) に作られます。つまり、一つの配列を表す変数に含まれる各要素のデータ型は、全て同じになります。ある特定の配列の、最初の要素は int 型で、二番目の要素は double 型であるということはありえません。また、一度初期化した配列の要素数は固定的であり、要素数を変更することはできません。そのような配列を使いたい場合は、 java.util.Vector クラスのインスタンスとして作成します。

配列の作成

配列の作り方に関しては、次の3つの方法が考えられます:

方法1方法2方法3
//宣言
int[] i;
//生成
i = new int[4];
//代入
i[0] = 1; i[1] = 2;
i[2] = 3; i[3] = 4;
//宣言と生成
int[] i = new int[4];
//代入
i[0] = 1; i[1] = 2;
i[2] = 3; i[3] = 4;
//宣言と代入
int[] i = {1, 2, 3, 4};

いずれにしても、同じ配列が作成されます。

配列型変数は次のようにも宣言できます:

int i[];

この場合のリテラルの代入は上記の記法と同じです。角括弧が、変数名の後ろに付くのか、データ型の後ろに付くのかの違いです。どちらも全く同じように解釈されます。

配列サイズ

配列のサイズ(要素の個数)は初期化時に決定しますが、後で変更することができません。たとえば、要素数を4つに定義した配列 array[] において、5番目の要素である array[4] を要求すると、実行時にエラー ArrayIndexOutOfBoundsException が発生します。このような実行時のエラーを Java では例外 (Exception) と呼びます。

一旦作った配列の要素数(サイズ)を変更することはできませんが、配列を参照する変数に、別のサイズの配列への参照を代入することはできます。

int[] array1 = new int[3];
int[] array2 = new int[10];
array1 = array2;	// O.K.!

詳細を説明する前に、参照型変数についておさらいします。

参照型変数

配列型変数は、基本データ型の変数とは異なります。

基本データ型の場合は、変数には具体的な値が保持されています。一方、配列型変数には、複数の要素の集団が代入されるわけですが、個々の要素が配列型変数に保持されているわけではありません。要素の具体的な値は別に保持されており、そこへの参照 (reference) が配列型変数に保持されています。

その意味では、配列を表す角括弧は変数名の後ろよりも、型の後ろの方が直感的かもしれません:

double[] dbl;
配列の参照
図:配列の参照

配列の個々の要素はメモリ上の別の位置に実体として存在し、変数名 dbl で確保されたメモリ領域には、その実体への参照(識別する為の ID)が保持されています。これは、前節で紹介した文字列や、あとで紹介する通常のクラス型変数の場合と同様です。

あくまでも参照ですから、一つの実体に対して、複数の参照を作ることが出来ます。詳しくは参照型変数の項で紹介します。

配列要素の初期化

基本データ型の変数の場合は、明示的に値を代入しないと利用することが出来ません。省略時の値が自動的に代入されたりはしません。

配列はオブジェクトの一つの型です。オブジェクトを参照する参照型変数の場合は、明示的に値を代入しなくとも、省略時の値が予め決められており、自動的に代入されます。参照型変数の省略時の値(デフォルト値)は null です。何も参照していないことを明示します。

byte0
short0
int0
long0L
float0.0F
double0.0
char'\u0000'
booleanfalse
参照型null

配列の代入

一般に、変数を代入すると、右辺から左辺に値がコピーされます。プリミティブ型の場合は、代入された値がコピーされますが、参照型の場合は、代入されるのは参照であって、参照先の配列がコピーされるわけではありません。

配列変数の代入
図:配列変数の代入

配列変数の型定義では、intString のような型と大括弧([])が指定されています。要素数を指定して実際に配列が作成されるのはその後です。つまり、変数自身には、要素数の情報は無く、要素に保持できる型と配列であることだけです。

よって、一旦配列として宣言された変数に、別の配列変数を代入するとき、要素の個数が異なっていても代入互換となります。

int[] array1 = new int[3];
int[] array2 = new int[10];
array1 = array2;	// O.K.!

配列変数は、型と大括弧の組が同じであれば、要素数によらず、代入互換だと覚えてください。

サンプル

小さい配列を参照する変数 small に、大きい配列の参照 big を代入して、配列変数は要素の値によらない配列を参照可能であることを確認します。

次に、コピー先の配列変数 small の要素値を変更して、元の配列変数 big の要素値も変更されていることを確認します。配列変数の代入が、同じ配列に対する参照のコピーであることが確認できます。

ArrayDemo.java:

class ArrayDemo {
	public static void main(String[] args) {
		int[] small = new int[5];
		int[] big   = new int[10];
		for (int i = 0; i < small.length; i++) {
			small[i] = i;
		}
		for (int i = 0; i < big.length; i++) {
			big[i] = i + 10;
		}
		
		System.out.println("初期状態");
		System.out.print("small: ");  pArray(small);
		System.out.print("big:   ");  pArray(big);
		// 配列変数の代入
		small = big;
		System.out.println("small = big;");
		System.out.print("small: ");  pArray(small);
		System.out.print("big:   ");  pArray(big);
		// コピー先の要素の更新
		small[5] = 100;
		System.out.println("small[5] = 100;");
		System.out.print("small: ");  pArray(small);
		System.out.print("big:   ");  pArray(big);
	}
	
	// 配列の要素をプリントするメソッド
	public static void pArray(int[] array) {
		for (int i = 0; i < array.length; i++) {
			System.out.print(" " + array[i]);
		}
		System.out.println();
	}
}

実行結果:

C:\java>javac ArrayDemo.java
C:\java>java ArrayDemo
初期状態
small:  0 1 2 3 4
big:    10 11 12 13 14 15 16 17 18 19
small = big;
small:  10 11 12 13 14 15 16 17 18 19
big:    10 11 12 13 14 15 16 17 18 19
small[5] = 100;
small:  10 11 12 13 14 100 16 17 18 19
big:    10 11 12 13 14 100 16 17 18 19
C:\java>


Copyright © 2001-2004 SUGAI, Manabu. All Rights Reserved.
SEO [PR] !uO z[y[WJ Cu