2013年9月22日日曜日

[Java][FindBugs]”VA_PRIMITIVE_ARRAY_PASSED_TO_OBJECT_VARARG”とは

FindBugs 2.0.2 / Java 6で検知できるパターンID:(VA_PRIMITIVE_ARRAY_PASSED_TO_OBJECT_VARARG)の意味が良くわかっていなかったのでメモしておきます。

このパターンについて、FindBugsのバグエクスプローラによる説明を改めて見てみます。
このコードは可変引数をとるメソッドにプリミティブ型の配列を渡しています。これは結局、要素型が配列である、サイズ1の配列が生成されて、その要素にこのプリミティブ型の配列が格納されてメソッドに渡されることになります。 
どういうことなの…?
そこで以下のコードを考えてみます。

 /**
  * 可変長引数に渡す変数がオブジェクトとプリミティブ型で挙動が異なる。
  */
 private void execute() {

  // オブジェクトの配列を渡す
  List<Integer> integerList = Arrays.asList(new Integer[] { 1, 2 });

  // プリミティブ型の配列を渡す
  List<int[]> intList = Arrays.asList(new int[] { 3, 4 });

 }
Arrays.asListは可変長引数を持つメソッドです。ローカル変数であるintegerListとintListの型を見てみると、integerListはIntegerのリストなのに、intListはint配列のリストになっています
直感的には、intListもintのリストになってくれてもいい気がします。
 
ここで、改めてバグエクスプローラの説明を見ます。
なるほど、確かにその通りでした。

結論としては、可変引数のメソッドはオブジェクトとプリミティブ型で挙動が違うから気をつけろ、ということが言いたいんですね。
まあ、上記コードのように戻り値があれば、違いは明らかなので問題は起きないと思います。

ちなみに、上記コードではFindBugsによって検知されません。

2013年9月12日木曜日