WisdomSoft - for your serial experiences.

7.6 配列宣言の混合表記

配列の宣言に用いるブラケット [ ] の位置は C++ のように変数名の後ろに指定する方法と、C# のように型の後ろに指定する方法が用意されています。どちらも同じ意味であり混在させることも可能です。

7.6.1 型にブラケットを指定する

配列型の変数を宣言するには、変数宣言文の識別子の直後にブラケットを指定しました。これは C/C++ 言語と互換性がある宣言方法なので、従来のプログラマにとって馴染みやすいでしょう。ところが、Java では、配列は 1 つの型であると考えることができます。その証拠に、配列型の変数は Object 型に変換することができます。だとすれば、識別子の後にブラケットを記述する文はむしろ奇妙ではないでしょうか。なぜならば、変数宣言文には型を記述するトークンが存在するからです。

Java 言語の変数宣言文では、変数の型を識別子の前に指定しました。例えば配列型 int[] は一つの方だと考えることができるのです。そのため、識別子の後にブラケットを指定して変数が配列であることをアピールする以外に、配列型として変数を宣言することも可能です。つまり、

int iArray[];

という変数宣言文は、整数型の変数 iArray が配列であることを表していますが、

int[] iArray;

に等しいと考えられます。この場合は整数型の配列 iArray 変数を宣言しています。結果はどちらも同じで、整数型の配列を参照する iArray 変数が宣言されます。前者は C/C++ 言語と互換性があるため、C/C++ を習得しているプログラマは前者を好むかもしれません。一方、後者の書き方は Microsoft .NET で使われている C# 言語の配列宣言と互換性があります。

コード
class Test {
	public static void main(String[] args) {
		int [] iArray = { 1 , 10 , 100 };
		int [][] iaa = { iArray , { 1000 , 10000 } };

		for(int i = 0 ; i < iaa.length ; i++) {
			for(int j = 0 ; j < iaa[i].length ; j++) {
				System.out.println("iaa[" + i + "][" + j + "] = " + iaa[i][j]);
			}
		}
	}
}
実行結果
>java Test
iaa[0][0] = 1
iaa[0][1] = 10
iaa[0][2] = 100
iaa[1][0] = 1000
iaa[1][1] = 10000

コード1は、変数宣言文の識別子ごとに配列を宣言するのではなく、配列型として iArray 変数と iaa 変数を宣言しています。これは記載方法が異なるというだけで、宣言文の結果はまったく同じです。iArray 変数は整数型の配列を参照し、iaa は整数型の配列の配列を参照します。何気に main() メソッドの args パラメータの書き方も変えています。

因みに、型にブラケットを指定する配列宣言と、識別子の後にブラケットを指定する配列宣言は、両方を混合することもできます。次のような配列宣言は、とても読みづらく感じますが構文上の問題ありません。

int[][] iArray[] , iaa[][] , iValue;

このような汚い宣言文でもコンパイルすることは可能です。この場合、型で指定したブラケットがそれぞれの変数に加算されます。つまり

int iArray[][][] , iaa[][][][] , iValue[][];

に等しい宣言であると考えられます。しかし、このような配列宣言の混合表記は意味のあるものではなく、単にソースの可読性を低くする要因となるだけです。型の後にブラケットを指定する方式か、識別子の後にブラケットを指定する方式のいずれかに統一するように意識しましょう。