Evet, a T...
sadece bir sözdizimsel şekerdir T[]
.
Listedeki son resmi parametre özeldir; bu türden sonra bir elips ile gösterilen değişken bir arity parametresi olabilir .
Son resmi parametre tipte bir değişken arity parametresiyse, tipte T
resmi bir parametre tanımlandığı kabul edilir T[]
. Yöntem bu durumda değişken bir arity yöntemidir. Aksi takdirde, sabit bir arity yöntemidir. Bir değişken arity yönteminin çağrılması, resmi parametrelerden daha fazla gerçek argüman ifadesi içerebilir. Değişken arity parametresinden önceki biçimsel parametrelere karşılık gelmeyen tüm gerçek argüman ifadeleri değerlendirilecek ve sonuçlar yöntem çağrısına geçirilecek bir diziye kaydedilecektir.
Aşağıda açıklamak için bir örnek verilmiştir:
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 ]"
}
Ve evet, yukarıdaki main
yöntem geçerlidir, çünkü tekrar, String...
sadece String[]
. Ayrıca, diziler kovaryant String[]
olduğu için a bir Object[]
, yani ezFormat(args)
her iki şekilde de çağırabilirsiniz .
Ayrıca bakınız
Varargs Gotchas # 1: Geçen null
Vararların nasıl çözüldüğü oldukça karmaşıktır ve bazen sizi şaşırtacak şeyler yapar.
Bu örneği düşünün:
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!!!
Varargs'ın nasıl çözüldüğüne bağlı olarak, son ifade objs = null
elbette neden NullPointerException
olur objs.length
. null
Bir varargs parametresine bir bağımsız değişken vermek istiyorsanız , aşağıdakilerden birini yapabilirsiniz:
count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"
İlgili sorular
Aşağıdakiler, insanların varargs ile uğraşırken sordukları bazı soruların bir örneğidir:
Vararg Gotchas # 2: Ekstra argümanlar ekleme
Bildiğiniz gibi, aşağıdakiler "işe yaramaz":
String[] myArgs = { "A", "B", "C" };
System.out.println(ezFormat(myArgs, "Z"));
// prints "[ [Ljava.lang.String;@13c5982 ][ Z ]"
Çünkü varargs çalışma şekli, ezFormat
aslında 2 argüman alır, ilki a String[]
, ikincisi a String
. Bir diziyi varargs'e geçiriyorsanız ve öğelerinin bağımsız değişkenler olarak tanınmasını istiyorsanız ve ayrıca bir bağımsız değişken eklemeniz gerekiyorsa , ekstra öğeyi barındıran başka bir dizi oluşturmaktan başka seçeneğiniz yoktur .
İşte bazı yararlı yardımcı yöntemler:
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;
}
Şimdi aşağıdakileri yapabilirsiniz:
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 Gotchas # 3: Bir dizi ilkel geçen
"Çalışmıyor":
int[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ [I@13c5982 ]"
Varargs yalnızca referans türleriyle çalışır. Otomatik boks ilkel dizi için geçerli değildir. Aşağıdaki işler:
Integer[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ 1 ][ 2 ][ 3 ]"