はい、a T...
はの構文糖にすぎませんT[]
。
リストの最後の仮パラメーターは特別です。タイプに続く省略記号で示される可変アリティパラメータである場合があります。
最後の仮パラメータがタイプの可変アリティパラメータである場合T
、それはタイプの仮パラメータを定義すると見なされますT[]
。このメソッドは可変アリティメソッドです。それ以外の場合は、固定アリティメソッドです。可変アリティメソッドの呼び出しには、仮パラメーターよりも実際の引数式が含まれる場合があります。可変引数パラメーターの前にある仮パラメーターに対応しないすべての実際の引数式が評価され、結果が配列に格納され、メソッド呼び出しに渡されます。
以下に例を示します。
public static String ezFormat(Object... args) {
String format = new String(new char[args.length])
.replace("\0", "[ %s ]");
return String.format(format, args);
}
public static void main(String... args) {
System.out.println(ezFormat("A", "B", "C"));
// prints "[ A ][ B ][ C ]"
}
そして、はい、上記main
再び、ための方法は、有効であるString...
だけですString[]
。また、配列は共変であるため、a String[]
はObject[]
なので、ezFormat(args)
どちらの方法でも呼び出すことができます。
こちらもご覧ください
Varargsの落とし穴#1:合格 null
可変引数がどのように解決されるかは非常に複雑であり、時には驚かれることがあります。
この例を考えてみましょう:
static void count(Object... objs) {
System.out.println(objs.length);
}
count(null, null, null); // prints "3"
count(null, null); // prints "2"
count(null); // throws java.lang.NullPointerException!!!
可変引数がどのように解決されるかにより、最後のステートメントはで呼び出されますがobjs = null
、これはもちろんで引き起こさNullPointerException
れobjs.length
ます。null
varargsパラメータに1つの引数を指定する場合は、次のいずれかを実行できます。
count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"
関連する質問
以下は、可変引数を扱うときに人々が尋ねたいくつかの質問のサンプルです。
Varargの落とし穴#2:追加の引数を追加する
ご存知のように、以下は機能しません。
String[] myArgs = { "A", "B", "C" };
System.out.println(ezFormat(myArgs, "Z"));
// prints "[ [Ljava.lang.String;@13c5982 ][ Z ]"
varargsの動作方法により、ezFormat
実際には2つの引数を取得します。最初の引数String[]
は、2番目の引数はString
です。配列をvarargsに渡し、その要素を個別の引数として認識させたい場合、さらに引数を追加する必要がある場合は、追加の要素に対応する別の配列を作成するしかありません。
いくつかの便利なヘルパーメソッドを次に示します。
static <T> T[] append(T[] arr, T lastElement) {
final int N = arr.length;
arr = java.util.Arrays.copyOf(arr, N+1);
arr[N] = lastElement;
return arr;
}
static <T> T[] prepend(T[] arr, T firstElement) {
final int N = arr.length;
arr = java.util.Arrays.copyOf(arr, N+1);
System.arraycopy(arr, 0, arr, 1, N);
arr[0] = firstElement;
return arr;
}
これで、次のことができます。
String[] myArgs = { "A", "B", "C" };
System.out.println(ezFormat(append(myArgs, "Z")));
// prints "[ A ][ B ][ C ][ Z ]"
System.out.println(ezFormat(prepend(myArgs, "Z")));
// prints "[ Z ][ A ][ B ][ C ]"
Varargsの落とし穴#3:プリミティブの配列を渡す
「動かない」:
int[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ [I@13c5982 ]"
Varargsは参照型でのみ機能します。オートボクシングはプリミティブの配列には適用されません。次の作品:
Integer[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ 1 ][ 2 ][ 3 ]"