2009-11-01 14 views
43

Rozważmy deklarację metoda:varargs i '...' argumentem

String.format(String, Object ...) 

Object ... argument jest po prostu odwołanie do tablicy Object s. Czy istnieje sposób użycia tej metody w odniesieniu do rzeczywistej tablicy Object? Jeśli przechodzą w Object tablicy do ... argument - będzie wartość argumentu Otrzymany się dwuwymiarową tablicą - ponieważ Object[] sama jest Object:

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

Zatem pierwszy składnik matrycy (co jest stosuje się w sposobie String.format) będzie tablica i będzie generować:

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

a następnie błąd, ponieważ rozmiar jest tablica 1.

Numeracja pogrubiona jest prawdziwym pytaniem.
To jest drugie pytanie: Czy tablica/parametr ... ma nazwę?

+1

Przepraszam, musiałem przetestować to przed pytaniem ... Myślę, że miałem ten problem dawno temu. –

Odpowiedz

52

Z docs on varargs:

Trzy okresy po rodzaju końcowego parametru wskazują, że ostatni argument mogą być przekazywane jako tablica lub sekwencja argumentów.

Możesz więc przekazywać wiele argumentów lub tablicę.

Poniższe działa dobrze:

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

Tak więc jeśli chcesz wywołać metodę za pomocą pojedynczego argumentu i zdarza się, że jest to tablica, musisz jawnie zawinąć ją w inną. 'method (new Object [] {tablica});' –

+8

lub wykonaj 'metodę ((Object) array)', która będzie automatycznie owijała się – naiad

+0

Lepiej niż przedtem widziałem te wyjaśnienia dotyczące parametrów vararg, ale wciąż po prostu tego nie rozumiem. – Sizons

11

Wystarczy przekazać tablicę:

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

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

Nie zamierzam nawet kłopotać dodawania własnej odpowiedzi, edytuj w "... jest znany jako argument vararg lub zmiennej i wymaga 0..n elementów określonych elementów" lub czegoś podobnego. – Esko

8

Sytuacja opisujesz będzie dość rzadko: przez większość czasu, swoje elementy varargs będzie String S lub numery lub Widget s .. To będzie niezwykłe, że będą Object s (może to być cokolwiek) lub tablice.

Ale jeśli argument varargs jest grono Object s lub typ tablicowy, wówczas pytanie ma powstać: można przekazać je w jedno pole, a następnie w jaki sposób kompilator wiedzieć, czy ma na celu przekazać tablicę (ten, który podałeś), lub serię 1 przedmiotu, który powinieneś umieścić w tablicy dla ciebie?

Szybki test pokazuje odpowiedź:

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); 
    } 
} 

Rezultatem wykonywania (dokładnej liczby będą różne:

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 

Więc odpowiedź brzmi, że w niejasnych przypadkach traktuje to, co przeszedł jako tablica zamiast tworzyć nową tablicę, aby ją zawijać. Ma to sens, ponieważ zawsze możesz zawrzeć ją w tablicy, jeśli chcesz inną interpretację.