web-dev-qa-db-fra.com

varargs et l'argument '...'

Considérez la déclaration de méthode:

String.format(String, Object ...)

L'argument Object ... N'est qu'une référence à un tableau de Objects. Existe-t-il un moyen d'utiliser cette méthode avec une référence à un tableau Object réel? Si je passe un tableau Object à l'argument ... - la valeur d'argument résultante sera-t-elle un tableau à deux dimensions - car un Object[] est lui-même un Object:

Object[] params = ....; // Make the array (for example based on user-input)
String s = String.format("%S has %.2f euros", params);

Ainsi, le premier composant du tableau (qui est utilisé dans la méthode String.format), Sera un tableau et il générera:

[class.getName() + "@" + Integer.toHexString(hashCode())] 

puis une erreur car la taille du tableau est 1.

La séquence bold est la vraie question.
Voici une deuxième question: n tableau/paramètre ... A-t-il un nom?

46

De la docs sur varargs :

Les trois périodes après le type du paramètre final indiquent que l'argument final peut être passé sous la forme d'un tableau ou d'une séquence d'arguments.

Vous pouvez donc passer plusieurs arguments ou un tableau.

Les éléments suivants fonctionnent très bien:

class VarargTest {
  public static void main(String[] args) {
    Object[] params = {"x", 1.2345f};
    String s = String.format("%s is %.2f", params);
    System.out.println(s); // Output is: x is 1.23
  }
}
54
Ayman Hourieh

Vous pouvez simplement passer un tableau:

public void foo(String... args) {
}

String args[] = new String[10];
foo(args);
11
cletus

La situation que vous décrivez sera assez rare: la plupart du temps, vos éléments varargs seront Strings, ou nombres, ou Widgets ... il sera inhabituel qu'ils soient Objects (qui pourrait être n'importe quoi) ou des tableaux.

Mais si l'argument varargs is un tas de Objects ou un type de tableau, alors votre question se pose: vous pouvez lui passer un seul tableau et comment le compilateur saura-t-il si vous vouliez dire passer un tableau (celui que vous avez fourni), ou une série de 1 élément qu'il devrait METTRE dans un tableau pour vous?

Un test rapide montre la réponse:

public class TestClass {
    public static void main(String[] args) {
        Object anObject = new Object();
        Object[] anArray = new Object[] {anObject, anObject};
        System.out.println("object1 = " + anObject);
        System.out.println("array1 = " + anArray);
        takesArgs();
        takesArgs(anObject, anObject);
        takesArgs(anArray); // is this the same as array1?
        takesArgs(anArray, anArray);
    }

    public static void takesArgs(Object... stuff) {
        System.out.println("The array was " + stuff);
    }
}

Le résultat de l'exécution (vos nombres exacts varieront:

object1 = Java.lang.Object@3e25a5
array1 = [Ljava.lang.Object;@19821f
The array was [Ljava.lang.Object;@addbf1
The array was [Ljava.lang.Object;@42e816
The array was [Ljava.lang.Object;@19821f
The array was [Ljava.lang.Object;@9304b1

Donc, la réponse est que dans des cas ambigus, il traite ce que vous avez passé comme un tableau au lieu de créer un nouveau tableau pour l'envelopper. Cela a du sens car vous pouvez toujours l'envelopper vous-même dans un tableau si vous souhaitez l'autre interprétation.

8
mcherm