Когда вы используете varargs в Java?

Я боюсь варгаров. Я не знаю, для чего их использовать.

Кроме того, опасно позволять людям передавать столько аргументов, сколько они хотят.

Какой пример контекста, который будет хорошим местом для их использования?

Ответ 1

Varargs полезны для любого метода, который должен иметь дело с неопределенным количеством объектов. Хорошим примером является String.format. Строка формата может принимать любое количество параметров, поэтому вам нужен механизм для передачи в любом количестве объектов.

String.format("This is an integer: %d", myInt);
String.format("This is an integer: %d and a string: %s", myInt, myString);

Ответ 2

Хорошее эмпирическое правило:

"Использовать varargs для любого метода (или конструктора), которому нужен массив T (любой тип T может быть) как входной.

Это упростит вызовы этих методов (не нужно делать new T[]{...}).

Вы можете расширить это правило, чтобы включить методы с аргументом List<T>, при условии, что этот аргумент предназначен только для ввода (т.е. список не модифицируется методом).

Кроме того, я бы воздержался от использования f(Object... args), потому что он скользит по пути программирования с неясными API-интерфейсами.

В терминах примеров я использовал его в DesignGridLayout, где я могу добавить несколько JComponent за один вызов:

layout.row().grid(new JLabel("Label")).add(field1, field2, field3);

В приведенном выше коде метод add() определяется как add(JComponent... components).

Наконец, реализация таких методов должна позаботиться о том, что его можно вызвать с помощью пустой vararg! Если вы хотите наложить хотя бы один аргумент, вы должны использовать уродливый трюк, например:

void f(T arg1, T... args) {...}

Я считаю этот трюк уродливым, потому что реализация метода будет менее простой, чем просто T... args в списке аргументов.

Надеется, что это поможет прояснить суть вопроса о varargs.

Ответ 3

Я часто использую varargs для вывода в журналы для отладки.

Практически каждый класс в моем приложении имеет метод debugPrint():

private void debugPrint(Object... msg) {
    for (Object item : msg) System.out.print(item);
    System.out.println();
}

Затем в методах класса у меня есть следующие вызовы:

debugPrint("for assignment ", hwId, ", student ", studentId, ", question ",
    serialNo, ", the grade is ", grade);

Когда я уверен, что мой код работает, я прокомментирую код в методе debugPrint(), чтобы в журналах не было слишком много посторонней и нежелательной информации, но я могу оставить отдельные вызовы debugPrint() раскомментирована. Позже, если я нахожу ошибку, я просто раскомментирую код debugPrint(), и все мои вызовы debugPrint() снова активируются.

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

private void debugPrint(String msg) {
    System.out.println(msg);
}

debugPrint("for assignment " + hwId + ", student " + studentId + ", question "
    + serialNo + ", the grade is " + grade);

Однако в этом случае, когда я комментирую код debugPrint(), сервер все равно должен решить проблему объединения всех переменных в каждом вызове debugPrint(), хотя ничего не происходит с полученной строкой, Однако, если я использую varargs, сервер должен только помещать их в массив, прежде чем он поймет, что он им не нужен. Сохраняется много времени.

Ответ 4

Varargs можно использовать, когда мы не уверены в количестве аргументов, которые должны быть переданы в методе. Он создает массив параметров неопределенной длины в фоновом режиме, и такой параметр можно рассматривать как массив во время выполнения.

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

Также, когда тип параметров будет изменяться, использование "Object... test" упростит код.

Например:

public int calculate(int...list) {
    int sum = 0;
    for (int item : list) {
        sum += item;
    }
    return sum;
}

Здесь косвенно массив типа int (list) передается как параметр и рассматривается как массив в коде.

Для лучшего понимания следуйте этой ссылке (это очень помогло мне в понимании этой концепции): http://www.javadb.com/using-varargs-in-java

P.S: Даже я боялся использовать varargs, когда я не знал этого. Но теперь я привык к этому. Как говорится: "Мы цепляемся за известного, боимся неизвестного", поэтому просто используйте его как можно больше, и вы тоже начнете его любить:)

Ответ 5

Varargs - это функция, добавленная в версии Java версии 1.5.

Зачем использовать это?

  • Что делать, если вы не знаете количество аргументов, передаваемых для метода?
  • Что делать, если вы хотите передать неограниченное количество аргументов в метод?

Как это работает?

Он создает массив с заданными аргументами и передает массив методу.

Пример:

public class Solution {



    public static void main(String[] args) {
        add(5,7);
        add(5,7,9);
    }

    public static void add(int... s){
        System.out.println(s.length);
        int sum=0;
        for(int num:s)
            sum=sum+num;
        System.out.println("sum is "+sum );
    }

}

Выход:

2

sum равно 12

3

сумма равна 21

Ответ 6

У меня тоже есть страх, связанный с варгарами:

Если вызывающий абонент передает в явном массиве метод (в отличие от нескольких параметров), вы получите общую ссылку на этот массив.

Если вам нужно сохранить этот массив внутренне, вы можете сначала его клонировать, чтобы не допустить, чтобы вызывающий абонент мог его изменить позже.

 Object[] args = new Object[] { 1, 2, 3} ;

 varArgMethod(args);  // not varArgMethod(1,2,3);

 args[2] = "something else";  // this could have unexpected side-effects

Хотя это не совсем отличается от передачи в любом виде объекта, состояние которого может измениться позже, так как массив обычно (в случае вызова с несколькими аргументами вместо массива), новый, созданный компилятором внутри, который вы можете безопасно использовать это, безусловно, неожиданное поведение.

Ответ 7

Я часто использую varargs для конструкторов, которые могут принимать какой-то объект фильтра. Например, большая часть нашей системы, основанная на Hadoop, основана на Mapper, который обрабатывает сериализацию и десериализацию элементов в JSON и применяет ряд процессоров, каждый из которых принимает элемент контента и либо модифицирует, либо возвращает его, либо возвращает null отклонить.

Ответ 8

В Java-документе Var-Args вполне очевидно использование var args:

http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html

об использовании он говорит:

"Итак, когда вы должны использовать varargs? Как клиент, вы должны использовать их каждый раз, когда API их предлагает. Важные применения в основных API-интерфейсах включают отражение, форматирование сообщений и новый объект printf. Как разработчик API, вы должны использовать их экономно, только когда преимущество действительно убедительно. Вообще говоря, вы не должны перегружать метод varargs, или программистам будет сложно выяснить, какая перегрузка вызвана. "