ProgrammingJava開発者

Javaにおけるvarargs(可変長引数)とは何か、それはどのように機能し、使用する際の落とし穴は何ですか?

Hintsage AIアシスタントで面接を突破

答え

Varargsは、メソッドが同じ型の可変数の引数を受け取ることを可能にする構文です。三点リーダーによって宣言されます:

public void printNames(String... names) { for (String name : names) { System.out.println(name); } }

これはどのように機能するのか?

Varargsパラメータは、メソッド内で対応する型の配列です:上記の例ではString[] namesです。任意の数の引数や配列を使用してメソッドを呼び出すことができます:

printNames("Igor", "Anna", "Maria"); printNames(new String[] {"Alex", "Inna"});

使用の際の注意点:

  • Varargsはメソッドのパラメータリストの最後のパラメータでなければなりません。
  • 1つのメソッドに対して、varargsパラメータは一つだけ許可されます。
  • 配列とvarargs、異なる型のvarargsとの間にオーバーロードがある場合、呼び出しの曖昧さが生じる可能性があります。
  • nullをvarargsに渡す場合、メソッドはnullを受け取りますが、空の配列ではありません!

ひっかけ問題

質問: 引数を渡さずにメソッドを呼び出した場合、varargsパラメータの配列の長さはどのくらいになりますか?

答え: この場合、varargs変数は長さ0の配列を参照します:new String[0]。nullにはなりません!

public void foo(Integer... args) { System.out.println(args.length); } // foo(); // 出力:0

このトピックの詳細を知らないことによる実際のエラーの例


物語

ロギングライブラリには、log(String... messages)というメソッドがあります。log(null)を呼び出すと、メソッド内でNullPointerExceptionが発生しました(messagesが空の配列になることを期待していましたが、実際にはnullでした)。解決するために明示的にnullをチェックする必要がありました。


物語

開発者はオーバーロードを作成しました:

public void doSomething(String[] arr) {...} public void doSomething(String... arr) {...}

配列を渡すと、期待していたメソッドではない方が呼び出され、データが失われました。配列とvarargsの違いは明白ではないことがわかりました。


物語

プロジェクトでvarargsの後に2番目のパラメータを追加しました:

public void foo(String... args, int count) {...} // コンパイルエラー!

これによりエラーが発生し、ビルドが中断されました。なぜなら、varargsは最後でなければならないからです。