読者です 読者をやめる 読者になる 読者になる

Arrays.asList はプリミティブ型の配列をリスト化してくれない

プリミティブ型の配列をリスト化してくれない。
いや、正確にはリスト化はしてくれるものの、プリミティブ型の配列全体を単一の要素として扱うため極めて直感と異なる動作をする。

//OK
Integer[] intArray = {1,2,3};
List<Integer> list = Arrays.asList(intArray);

//NG
int[] primitiveIntArray = {1,2,3};
List<Integer> list = Arrays.asList(primitiveIntArray);

上記のNGパターンをコンパイルが通るようにすると以下のようになる。

int[] primitiveIntArray = {1,2,3}; 
List<int[]> list = Arrays.asList(primitiveIntArray);

なんとも不便。なぜこんなことが起こるのかというと、可変長引数の仕様に原因がある。
可変長引数に配列を渡した場合、オブジェクトの配列は展開されるがプリミティブ型の配列は展開されないのだ。


サンプルコード

// 可変長引数の中身を表示するだけのメソッド
public static <T> void numargs( T... args ) {
	for( T o : args )
		System.out.print( o + " " );
	
	System.out.println();
}

//上記メソッドに int 配列と Integer 配列を渡す
numargs( new int[]{1,2,3} );
numargs( new Integer[]{1,2,3} );

実行結果

[I@1a758cb 
1 2 3 

・・・というわけで、Arrays.asList が悪いわけではなく可変長引数の仕様が悪い。
Autoboxing?なにそれおいしいの?