Когда предпочесть массив varargs массиву? - PullRequest
10 голосов
/ 31 октября 2011

Я реализую API, у меня есть метод, по которому вы передаете список путей, по которым программа читает ресурсы из

public void importFrom(String... paths) {

}

Я использую varargs, чтобы сделать вызов метода максимально удобным для пользователя, например,

obj.importFrom("/foo", "/foo/bar);

Это правильное использование вараггов? Или лучше передать массив?

Ответы [ 4 ]

8 голосов
/ 31 октября 2011

В вашем случае с varargs все в порядке. На самом деле вам не нужно создавать массив путей, которые вы будете импортировать, потому что вы ничего не хотите делать с этими путями, кроме как передать их в свой метод importFrom.

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

Кстати, вы можете по-прежнему передавать массив, если хотите

public class VarargsDemo {
    public static void f(String... args) {
        for (String s: args) {
            System.out.println(s);
        }
    }
    public static void main(String[] args) {
        String[] english = new String[]{"one", "two", "three"};
        f(english);
        f("uno", "dos", "tres");
    }
}

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

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

Тем не менее, основное ограничение для varargs состоит в том, что такой параметр должен быть последним в методе. В вашем случае это не проблема, но в целом это то, что нужно учитывать.

3 голосов
/ 31 октября 2011

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

public void importFrom(String... paths)
{
}

компилируется в

public void importFrom(String[] paths)
{
}

В качестве альтернативы вы также можете использовать Iterable<String>, чтобы упростить передачу аргументов как коллекции.

2 голосов
/ 31 октября 2011

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

1 голос
/ 31 октября 2011

Я думаю, что другой альтернативой является использование List<String>.Лично я бы использовал List, если есть несколько аргументов или если аргументы автоматически обрабатываются откуда-то (например, анализируется из файла).

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

...