可変長引数の制約とオーバーロード優先順位
最後の引数にしか置けません。通常のオーバーロードが優先される順序も解説します。
エラーメッセージの読み方
Main.java:8: error: method sum in class Main cannot be applied to given types;
Main.java- ファイル名
8- 行番号 — javacが異常に気づいた位置。原因の行とは限りません
error- 種別 — コンパイルエラー。実行まで到達しません
method sum in class Main cannot be applied to given types;- 内容 — javacが期待していたもの、または見つけられなかったもの
このエラーが出る典型パターン
パターン1
1 public class Main { 2 static int sum(int[] nums) { ^ 3 int t = 0; 4 for (int n : nums) t += n; 5 return t; 6 } 7 public static void main(String[] args) { 8 System.out.println(sum(1, 2, 3)); 9 } 10 }
Main.java:8: error: method sum in class Main cannot be applied to given types;
required: int[] found: int,int,int
可変長引数は型の後に ... を書きます。呼び出し側はカンマ区切りでも配列でも渡せます。
直し方: [] を ... にします。
広告
広告スロット(未設定)
パターン2
1 public class Main { 2 static void log(String tag, int... nums, String args) { ^ 3 System.out.println(tag + args.length); 4 } 5 public static void main(String[] args) { 6 log("x", 1, 2); 7 } 8 }
Main.java:2: error: varargs parameter must be the last parameter
可変長引数は必ず最後の引数にします。複数置くこともできません。
直し方: int... nums, String を Object... にします。
パターン3
1 public class Main { 2 static void f(Object... a) { System.out.println("varargs"); } 3 static void f(Object a) { System.out.println("single"); } 4 public static void main(String[] args) { 5 f("x" ); ^ 6 } 7 }
出力: single(引数1つのときは可変長より通常のオーバーロードが優先されます)
可変長引数は最後の候補として選ばれます。曖昧さを避けるため、同名で両方定義しないのが安全です。
直し方: "x" を "x" にします。
よくある誤解
引数ゼロでも呼び出せます。渡されなかった場合はnullではなく長さ0の配列になるので、nullチェックではなくlengthを見ます。
まとめ
可変長引数の制約とオーバーロード優先順位は上級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。