2014-12-29 3 views
6

я просто наткнулся varargs во время обучения андроида (doInBackground(Type... params)), SO сообщений разъяснила использовать егоПочему мы не можем использовать массивы вместо varargs?

Мой вопрос, почему мы не можем просто использовать массивы вместо varargs

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

я могу замените этот тип вызова путем упаковки моего переменного количества аргументов в массиве и передачи его методу, подобному этому

public void foo(String[] alternativeWay){ } 

делает также в использовании Java varargsmain(String[] args), если не так, как мы в состоянии передать параметры рабочей среды в ней

Пожалуйста, предложите преимущества или использование varargs и есть ли что-нибудь еще важно знать о varargs

+3

является переменным числом аргументов синтаксического удобства. Перед varargs мы использовали записи создания массива в долгосрочной перспективе. –

+0

@MarkoTopolnik Не могли бы вы рассказать о главном? –

+1

Вы можете объявить 'main (String ... args)', если хотите. Это не будет иметь никакого значения. –

ответ

11

Единственные разница между

foo(String... strings) 

и

foo(String[] strings) 

для , вызывающий код. Рассмотрю этот вызов:

foo("a", "b"); 

Это действует с первой декларацией foo, и компилятор будет выдавать код, чтобы создать массив, содержащие ссылки на "a" и "b" во время выполнения. Это не действителен со вторым объявлением foo, хотя, поскольку он не использует varargs.

В любом случае, это хорошо для вызывающего абонента в явно создать массив:

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

также делает основной (String [] арг) в использовании Java переменной длины, если не так, как мы находимся в состоянии для передачи параметров времени выполнения

Когда это написано как main(String[] args), это не так; если вы напишете main(String... args), то это произойдет. Не имеет значения, как JVM относится к нему, потому что инициализация JVM создает массив с аргументами командной строки. Это будет иметь значение только в том случае, если вы пишете свой собственный код, чтобы явно ссылаться на main.

+1

И вы можете назвать это без аргументов. – wvdz

+0

@popovitsj: Да, хотя это приведет к созданию пустого массива. –

+1

... как вы можете назвать вторую форму с массивом длины 0 - но это гораздо больше усилий по набору текста :) – laune

4

Мы можем использовать массивы вместо varargs. Varargs - синтаксический сахар для использования массивов. Но они делают ваш код более компактным и читаемым. Сравнить

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

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

с

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

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

Аналогичным образом, нам не нужен оператор бриллиантом (<>, Java 7) или лямбды (Java 8) либо. Но они делают код более читабельным и, следовательно, более удобным.

1

Одно из преимуществ varargs - это методы, требующие хотя бы одного параметра, например max. С списков параметров вы можете сделать это, как этот

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

Это является большим, потому что это невозможно не передавать никаких параметров метода max, и вызывающий код для max действительно чист: max(2, 4, 1, 8, 9). Без varargs единственным способом принудительного выполнения условия, по которому должно быть передано хотя бы одно число, было бы исключение во время выполнения, если массив имел длину 0 (всегда лучше всего избегать) или заставить вызывающего абонента написать max(2, new int[] {4, 1, 8, 9}), что действительно некрасиво.

1

Поскольку вы действуете вызов выглядит как вызов функции, напр .:

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

выглядит лучше, чем:

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

Там нет магии за AsyncTask, очень часто вы действительно не нужно передавать любые параметры, иногда вы передаете параметры конструктору вместо выполнения. Есть также реализации в AsyncTask:

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

что не использовать переменную длину на всех

Смежные вопросы