Oui, un T...
est seulement un sucre syntaxique pour un T[]
.
Le dernier paramètre formel dans une liste est spécial ; il peut être un arité variable indiqué par une elipsis suivant le type.
Si le dernier paramètre formel est un paramètre d'arité variable de type T
on considère que l'on définit un paramètre formel de type T[]
. La méthode est alors une arité variable méthode. Sinon, il s'agit d'une arité fixe méthode. Les invocations d'une méthode d'arité variable peuvent contenir plus d'expressions d'arguments réels que de paramètres formels. Toutes les expressions d'arguments réels qui ne correspondent pas aux paramètres formels précédant le paramètre d'arité variable seront évaluées et les résultats seront stockés dans un tableau qui sera transmis à l'invocation de la méthode.
Voici un exemple à titre d'illustration :
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, ce qui précède main
est valable, parce qu'encore une fois, String...
est juste String[]
. De plus, comme les tableaux sont covariants, un String[]
es un Object[]
Vous pouvez donc également appeler ezFormat(args)
de toute façon.
Voir aussi
Varargs gotchas #1 : passing null
La façon dont les varargs sont résolus est assez compliquée, et parfois elle fait des choses qui peuvent vous surprendre.
Prenons 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 varargues sont résolus, la dernière instruction est invoquée avec la commande objs = null
ce qui, bien sûr, causerait NullPointerException
con objs.length
. Si vous voulez en donner un null
à un paramètre varargs, vous pouvez faire l'une des deux choses suivantes :
count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"
Questions connexes
Voici un échantillon de certaines des questions posées par des personnes qui traitent des varargs :
Vararg gotchas #2 : ajouter des arguments supplémentaires
Comme vous l'avez constaté, ce qui suit ne "fonctionne" 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 les varargues fonctionnent, ezFormat
reçoit en fait 2 arguments, le premier étant un String[]
le second étant un String
. Si vous passez un tableau à varargs, et que vous voulez que ses éléments soient reconnus comme des arguments individuels, et que vous avez aussi besoin d'ajouter un argument supplémentaire, alors 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 faire ce qui suit :
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 : passer un tableau de primitives
Cela ne "marche" pas :
int[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ [I@13c5982 ]"
Varargs ne fonctionne qu'avec les types de référence. L'autoboxage ne s'applique pas aux tableaux de primitives. Ce qui suit fonctionne :
Integer[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ 1 ][ 2 ][ 3 ]"
8 votes
Je ne peux pas m'empêcher de me demander pourquoi cette question est du genre "est-ce valable". Vous ne pouviez pas simplement essayer ? N'exagérez pas la question, vous vous ferez plus de mal que de bien.
33 votes
C'est vrai, cela aurait pu être facilement testé. cependant, l'avantage d'une question comme celle-ci est qu'elle expose le sujet et suscite des réponses intéressantes.
3 votes
J'ai en fait essayé le code ci-dessus, avec l'intention de passer le tableau args comme arguments à la méthode. Cependant, je n'ai pas réalisé que j'aurais dû ajouter extraVar à args en premier. Quand on sait que les arguments de variables sont traités comme un tableau (même en dehors de la méthode), c'est bien sûr tout à fait logique.