it-swarm.com.ru

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

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

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

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

189
Harry Quince

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

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

Хорошее практическое правило будет:

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

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

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

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

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

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

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

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

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

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

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

78
jfpoilpret

Я часто использую 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, сервер должен только поместить их в массив, прежде чем он поймет, что он им не нужен. Много времени сэкономлено.

34
bob

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

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

12
Sarvan

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

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

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

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

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

Пример :

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

сумма 12

3

сумма 21

11
Arun Prakash

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

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

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

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

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

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

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

5
Thilo

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

1
Kevin Peterson

В Java doc Var-Args совершенно очевидно использование var args:

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

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

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

1
Surendra