Oui, a T...
n'est qu'un sucre syntaxique pour a T[]
.
Le dernier paramètre formel d'une liste est spécial; il peut s'agir d'un paramètre d' arité variable , indiqué par une élipse suivant le type.
Si le dernier paramètre formel est un paramètre d'arité variable de type T
, il est considéré comme définissant un paramètre formel de type T[]
. La méthode est alors une méthode à arité variable . Sinon, c'est une méthode d' arité fixe . Les invocations d'une méthode d'arité variable peuvent contenir des expressions d'argument plus réelles que des paramètres formels. Toutes les expressions d'argument réelles qui ne correspondent pas aux paramètres formels précédant le paramètre d'arité variable seront évaluées et les résultats stockés dans un tableau qui sera transmis à l'appel de méthode.
Voici un exemple pour illustrer:
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 ]"
}
Et oui, la main
méthode ci-dessus est valide, car encore une fois, elle String...
est juste String[]
. De plus, comme les tableaux sont covariants, a String[]
est un Object[]
, vous pouvez donc également appeler dans les ezFormat(args)
deux sens.
Voir également
Varargs gotchas # 1: en passant null
La façon dont les varargs sont résolus est assez compliquée, et parfois cela fait des choses qui peuvent vous surprendre.
Considérez cet exemple:
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!!!
En raison de la façon dont les varargs sont résolus, la dernière instruction invoque avec objs = null
, ce qui bien sûr entraînerait NullPointerException
avec objs.length
. Si vous souhaitez donner un null
argument à un paramètre varargs, vous pouvez effectuer l'une des opérations suivantes:
count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"
Questions connexes
Voici un exemple de certaines des questions que les gens ont posées lorsqu'ils ont traité des varargs:
Vararg gotchas # 2: ajout d'arguments supplémentaires
Comme vous l'avez découvert, les éléments suivants ne "fonctionnent" pas:
String[] myArgs = { "A", "B", "C" };
System.out.println(ezFormat(myArgs, "Z"));
// prints "[ [Ljava.lang.String;@13c5982 ][ Z ]"
En raison de la façon dont varargs fonctionne, ezFormat
obtient en fait 2 arguments, le premier étant un String[]
, le second étant un String
. Si vous passez un tableau à varargs, et que vous souhaitez que ses éléments soient reconnus comme des arguments individuels, et que vous devez également ajouter un argument supplémentaire, vous n'avez pas d'autre choix que de créer un autre tableau qui accueille l'élément supplémentaire.
Voici quelques méthodes d'aide utiles:
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;
}
Vous pouvez maintenant effectuer les opérations suivantes:
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: passage d'un tableau de primitives
Ça ne "marche" pas:
int[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ [I@13c5982 ]"
Varargs ne fonctionne qu'avec des types de référence. Le contrôle automatique ne s'applique pas au tableau de primitives. Les oeuvres suivantes:
Integer[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ 1 ][ 2 ][ 3 ]"