Java'da değişken bağımsız değişken bir yöntem için bağımsız değişken olarak bir dizi geçebilir miyim?
Gibi bir işlevi oluşturmak mümkün olmak istiyorum
class A {
private String extraVar;
public String myFormat(String format, Object ... args){
return String.format(format, extraVar, args);
}
}
Sorun burada args
tedavi Object[]
yöntem myFormat
ve böylece, tek bir argüman String.format
, süre istiyorum her Object
args
olmak geçtikçe yeni bir argüman. String.format
da değişken bağımsız değişken bir yöntem olduğu için, bu mümkün olmalıdır.
Eğer bu mümkün değilse, String.format(String format, Object[] args)
gibi bir yöntem var mı? Bu durumda args
18 *yeni bir dizi kullanarak önüne ve bu yönteme geçerim.
CEVAP
Evet, bir T...
T[]
için bir sözdizimsel şekerdir.
JLS 8.4.1 Format parameters
Bir listedeki son resmi parametre özel değil, olabilirdeğişken sunarparametre türü aşağıdaki bir elipsis ile gösterilir.
Eğer son resmi parametre değişkenin türü parametre bir parametre
T
, 23* *yazın resmi bir parametre tanımlamak için kabul edilir. Bu yöntem o zamandeğişken sunaryöntem. Aksi takdirde, birparametre sabityöntem. Değişken parametre bir yöntem çağırmaları resmi parametreleri daha gerçek bağımsız değişken ifadeler içerebilir. Biçimsel parametre değişken parametre parametre önceki karşılık gelen tüm gerçek bağımsız değişken ifadeleri değerlendirilecek ve sonuçlar yöntem çağırma için geçirilen bir dizi içine saklı.
Burada göstermek için bir örnek:
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, main
yukarıdaki yöntemi tekrar, String...
String[]
olduğu için geçerli değil. Diziler kovaryant çünkü, bir String[]
Object[]
da ezFormat(args)
her iki şekilde de arayabilirsin.
Ayrıca Bkz
Varargs sorunlar #1: geçme null
Nasıl çözüldüğünü oldukça karmaşık ve bazen sizi şaşırtabilecek şeyler yapar.
Örnek:
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!!!
Nasıl çözüldüğünü nedeniyle, son ifade objs.length
elbette NullPointerException
neden olacak objs = null
ile çağırır. Eğer bir varargs bir parametre için null
kanıt vermek istiyorsanız, aşağıdakilerden birini yapabilirsiniz:
count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"
İlgili sorular
Aşağıdaki kişiler varargs ile ilgili sorulan soruların birkaç örnek:
- bug with varargs and overloading?
- How to work with varargs and reflection
- Most specific method with matches of both fixed/variable arity (varargs)
Sırasında sorunlar #2: ekleme ekstra argümanlar
Öğrenmiş olduğunuz gibi, aşağıdaki değil "":
String[] myArgs = { "A", "B", "C" };
System.out.println(ezFormat(myArgs, "Z"));
// prints "[ [Ljava.lang.String;@13c5982 ][ Z ]"
Çünkü varargs çalışmak, ezFormat
aslında 2 argüman, ilk ** 40, ikinci bir String
olmak alır. Varargs için bir dizi geçirmeden, ve öğeleri tek tek bağımsız değişken olarak kabul edilmesi ve ayrıca bir ek argüman eklemek gerekirse, ama oluşturmak için başka seçeneğiniz yokbaşka bir diziekstra unsuru barındırmaktadır.
İş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 ipuçları #3: geçen ilkel bir dizi
Değil mi "":
int[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ [I@13c5982 ]"
Varargs yalnızca başvuru türleri ile çalışır. Autoboxing ilkellerin dizi için geçerli değildir. Aşağıdaki çalışır:
Integer[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ 1 ][ 2 ][ 3 ]"