2014-12-29 17 views
6

Właśnie natknąłem varargs podczas nauki Android (doInBackground(Type... params)) SO posty wyjaśnić korzystanie z niejDlaczego nie możemy po prostu użyć tablic zamiast varargs?

Moje pytanie brzmi, dlaczego nie możemy po prostu użyć tablic zamiast varargs

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

mogę zamień ten typ wywołania, pakując zmienną liczbę argumentów w tablicy i przekazując go do metody, takiej jak ta robi także main(String[] args) w użyciu java varargs, jeśli nie jak jesteśmy w stanie przekazać parametry wykonawcze do niej

proszę sugerować korzyści lub wykorzystanie varargs i jest tam coś jeszcze ważne, aby wiedzieć o varargs

+3

varargs jest składniowym wygoda. Przed varargsami pisaliśmy długie wyrazy tworzenia tablic. –

+0

@MarkoTopolnik Czy możesz dopracować i co z głównym? –

+1

Możesz zadeklarować 'main (String ... args)' jeśli chcesz. To nie ma znaczenia. –

Odpowiedz

11

jedynym różnica między

foo(String... strings) 

i

foo(String[] strings) 

jest dla kodu dzwoniąc pod numer. Rozważmy następujący apel:

foo("a", "b"); 

to ważne z pierwszą deklaracją foo, a kompilator będzie emitować kod, aby utworzyć tablicę zawierającą odnośniki do "a" i "b" w czasie wykonywania. Jest to nie ważne z drugą deklaracją foo, ponieważ to nie używa varargs.

W obu przypadkach jest to dobre dla rozmówcy do wyraźnie utworzyć tablicę:

for(new String[] { "a", "b" }); // Valid for either declaration 

także ma main (String [] args) w użyciu java varargs, jeśli nie jak jesteśmy w stanie do przekazania parametrów środowiska wykonawczego do niego

Kiedy jest napisany jako main(String[] args), nie jest; jeśli napiszesz main(String... args), to robi to. Nie ma znaczenia, jak JVM to traktuje, ponieważ inicjalizacja JVM tworzy tablicę z argumentami wiersza poleceń. Miałoby to znaczenie tylko wtedy, gdybyś pisał własny kod, aby jawnie wywołać main.

+1

Możesz też wywoływać to bez żadnych argumentów. – wvdz

+0

@popovitsj: Tak, chociaż to spowoduje utworzenie pustej tablicy. –

+1

... jak można nazwać drugi formularz z tablicą o długości 0 - ale jest to znacznie więcej wysiłku pisania :) – laune

4

Możemy użyć tablic zamiast varargs. Varargs to cukier syntaktyczny do używania tablic. Ale sprawiają, że twój kod jest bardziej zwarty i czytelny. Porównaj

private void foo(String... ss) { ... } 

private void bar() { 
    ... 
    foo("One", "Two", "Three"); 
    ... 
} 

z

private void foo(String[] ss) { ... } 

private bar() { 
    ... 
    foo(new String[] { "One", "Two", "Three" }); 
    ... 
} 

Podobnie, nie potrzebujemy operatora diamentowe (<>, 7) lub Java (Java lambdy 8) albo. Ale sprawiają, że kod jest bardziej czytelny, a przez to łatwiejszy w utrzymaniu.

1

Jedną z zalet programu varargs jest metoda wymagająca zastosowania co najmniej jednego parametru, takiego jak max. Z varargs można to zrobić jak ten

static int max(int first, int... remaining) { 
    int max = first; 
    for (int number : remaining) 
     max = Math.max(max, number); 
    return max; 
} 

To jest dobre, bo to jest niemożliweprzekazać żadnych parametrów do metody max, i kod wywołujący dla max jest naprawdę czyste: max(2, 4, 1, 8, 9). Bez varargs jedynym sposobem, aby wymusić warunek, że przynajmniej jeden numer powinien zostać przekazany, byłoby wyrzucenie wyjątku w czasie wykonywania, jeśli tablica ma długość 0 (zawsze najlepiej unikać) lub zmusić rozmówcę do napisania max(2, new int[] {4, 1, 8, 9}), która jest naprawdę brzydki.

1

Bo funkcjonować wywołanie wygląda bardziej jak wywołania funkcji, np .:

new MyAsyncTask().execute("str1", "str2"); 

wygląda lepiej niż:

new MyAsyncTask().execute(new String[]{"str1", "str2"}); 

Nie ma magicznej za AsyncTask, bardzo często naprawdę nie trzeba przekazać dowolne parametry, czasami przekazujesz parametry do konstruktora zamiast wykonać. Istnieją również implementacje AsyncTask:

https://github.com/roboguice/roboguice/blob/master/roboguice/src/main/java/roboguice/util/SafeAsyncTask.java

że nie stosowanie varargs na wszystkich

Powiązane problemy