2009-11-01 11 views
43

Tenir compte de la déclaration de la méthode:varargs et '...' argument de

String.format(String, Object ...) 

L'argument Object ... est juste une référence à un tableau de Object s. Existe-t-il un moyen d'utiliser cette méthode avec une référence à une matrice réelle Object? Si je passe dans un tableau Object à l'argument ... - sera la valeur d'argument qui en résulte être une matrice à deux dimensions - parce qu'un Object[] lui-même est 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 élément du tableau (ce qui est utilisé dans la méthode String.format), sera un tableau et il va générer:

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

puis une erreur, car la taille du tableau est 1.

La séquence BOLD est la vraie question.
Ceci est une deuxième question: Un tableau/paramètre ... a-t-il un nom?

+1

Désolé, j'ai dû tester avant de demander ... Je pense que j'ai eu ce problème il y a longtemps. –

Répondre

52

De l'docs on varargs:

Les trois périodes après le type de paramètre finale indiquent que le dernier argument peut être passé comme tableau ou en tant que séquence d'arguments.

Vous pouvez donc transmettre plusieurs arguments ou un tableau.

Les travaux suivants 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 
    } 
} 
+1

Donc, si vous voulez appeler la méthode avec un seul argument et qu'il s'agit d'un tableau, vous devez l'inclure explicitement dans un autre. 'method (new Object [] {array});' –

+8

ou faire 'method ((Object) array)', qui s'auto-enveloppe – naiad

+0

Je suis mieux qu'avant d'avoir vu ces explications sur les paramètres de vararg, juste ne comprends pas. – Sizons

11

Vous pouvez juste passer un tableau:

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

String args[] = new String[10]; 
foo(args); 
+0

Je ne vais même pas me donner la peine d'ajouter ma propre réponse, éditer dans "... est connu comme vararg ou arguments variables et nécessite 0..n éléments d'éléments spécifiés" ou quelque chose comme ça. – Esko

8

La situation que vous décrivez va être assez rare: la plupart du temps, vos articles varargs sera String s, ou des chiffres, ou Widget s .. il sera inhabituel pour eux d'être Object s (ce qui pourrait être n'importe quoi) ou des tableaux.

Mais si l'argument varargs est un tas de Object s ou un type tableau, votre question ne se pose: vous pouvez passer un seul tableau et comment si vous vouliez dire connaître le compilateur de passer un tableau (celui que vous avez fourni), ou une série de 1 objet 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 chiffres exacts varient:

object1 = [email protected] 
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 

La réponse est que dans les cas ambigus, il traite ce que vous avez passé comme le tableau au lieu de créer un nouveau tableau pour l'envelopper, ce qui est logique car vous pouvez toujours l'envelopper dans un tableau si vous voulez l'autre interprétation.