List型からのtoArray

以下のようにjava.util.List#toArray()では、引数に配列型のインスタンスを渡して配列の型を確定します。

List<SampleBean> list = new ArrayList<SampleBean>();
SampleBean[] res = list.toArray(new SampleBean[0]);

引数で空インスタンスを渡さないと、Object[]として返すのでClassCastExceptionが発生します。


List型でジェネリクスを指定している場合、(オブジェクトを触る側からすると)既に配列にすべき型は分かっているので、以下のように書けてもいいのではないかと思ったりするわけですが、

SampleBean[] res = list.toArray();

ArrayListの実装などを読んでみたところ、現状ではちょっと難しそうです。後方互換性の問題ではなく、Javaジェネリクスの仕様的に不可能にみえます。引数で型を受け取っていなければ、型を確定させる手段がありません。

ArrayListの場合、内部的に持っているelementData(配列)の型を取ってくれば引数ありtoArrayがやっている事を内部的に完結できそうですが、これだと要素が全てnullの場合(例えばnewしただけのList)に型を確定できません。


私は、以下のようなArrayUtil#toArray()を作って使ったりしますが、このutilはやはり上記の問題を解決できていなくて、size()が0の場合はnullで返しています。

主な用途がReflection APIで配列にして引数に渡すケースなので、問題はないのですが。

public static <T> T[] toArray(List<T> arg)
{
	if (arg == null)
		return null;
	int len = arg.size();
	if (len <= 0)
		return null;
	Class<?> clazz = arg.get(0).getClass();
	T[] retArr = (T[]) Array.newInstance(clazz, len);
	for (int i = 0; i < len; i++)
		retArr[i] = arg.get(i);
	return retArr;
}