なにこれ?
Javaではメソッド定義で可変長引数を設定できますが、その引数にリストを渡すときは注意しないといけないよという話です。
そもそも可変長引数とは?
メソッドの引数として個数が任意のものです。
例えばString.formatでは以下のように第1引数に書式文字列、第2引数に書式指示子(%s, %dとか)によって参照される引数を渡しますが、この第2引数は要素数が可変です。
public static String format(String format, Object... args)
このため、以下のように第2引数以降は好きな数だけ引数を渡せます。
sample.java
public class Main {
public static void main(String[] args) {
System.out.println(String.format("メッセージです"));
System.out.println(String.format("%s宛のメッセージです", "太郎"));
System.out.println(String.format("%sから%s宛のメッセージです", "太郎", "花子", "次郎"));
System.out.println(String.format("%sから%s宛のメッセージです", new String[] {"太郎", "花子"}));
}
}
出力結果
メッセージです
太郎宛のメッセージです
太郎から花子宛のメッセージです
太郎から花子宛のメッセージです
渡す引数が書式指示子より多い場合は、余分なものは無視されます。
また、引数は配列として渡すことも可能です。
可変長引数にリストを渡す
さて、可変長引数に配列を渡すことで、配列内の要素を参照することができましたが、リストを渡すとどうなるでしょうか?
sample.java
import java.util.*;
public class Main {
public static void main(String[] args) {
// 配列を渡した場合
System.out.println("引数のサイズ:" + calcArgSize(new Integer[] {1, 2, 3}));
// リストを渡した場合
System.out.println("引数のサイズ:" + calcArgSize(List.of(1, 2, 3)));
}
public static Integer calcArgSize(Object... args) {
return args.length;
}
}
このとき結果は次のようになります。
console
引数のサイズ:3
引数のサイズ:1
これはリストを渡した場合は、引数がObject[] {List}として処理されるからです。
なので、配列と同様にサイズが不定の引数をリストとして渡すには、いったん配列に変換してやる必要があります。
sample2.java
import java.util.*;
public class Main {
public static void main(String[] args) {
// 配列を渡した場合
System.out.println("引数のサイズ:" + calcArgSize(new Integer[] {1, 2, 3}));
// リストを変換して渡した場合
System.out.println("引数のサイズ:" + calcArgSize(List.of(1, 2, 3).toArray()));
}
public static Integer calcArgSize(Object... args) {
return args.length;
}
}
console
引数のサイズ:3
引数のサイズ:3