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

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

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

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

8 ответов


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

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

хорошее правило было:

"используйте 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.


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


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

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

также, если тип параметров будет меняться затем с помощью "объекта...тест " значительно упростит код.

например:

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, когда я не знал об этом. Но теперь я я привык к этому. Как говорится: "мы цепляемся за известное, боимся неизвестного", поэтому просто используйте его как можно больше, и вам тоже начнет это нравиться :)


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


У меня тоже есть страх, связанный с 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

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


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


в 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, или программистам будет сложно выяснить, какая перегрузка вызывается. "