Вопрос

Рассмотрим следующие сигнатуры методов:

public fooMethod (Foo[] foos) { /*...*/ }

и

public fooMethod (Foo... foos) { /*...*/ }

Объяснение:Первый принимает в качестве аргумента массив объектов Foo – fooMethod(new Foo[]{..}) - в то время как последний принимает произвольное количество аргументов типа Foo и представляет их как массив Foo:s внутри метода - fooMethod(fooObject1, fooObject2, etc...).

Java устраивает недовольство, если определены оба метода, утверждая, что они являются дублирующими методами.Я провел некоторую детективную работу и обнаружил, что первое объявление действительно требует явного массива объектов Foo, и это единственный способ вызвать этот метод.Второй способ фактически принимает как произвольное количество аргументов Foo, так и массив объектов Foo.

Итак, вопрос в том, поскольку последний метод кажется более гибким, есть ли какие-либо причины использовать первый пример или я упустил что-то важное?

Это было полезно?

Решение

Эти методы на самом деле одинаковы.

Эта функция называется varargs и является функцией компилятора.За кулисами это перевод на прежнюю версию.

Существует ловушка, если вы определяете метод, который принимает Object...и вы отправили один параметр типа Object[]!

Другие советы

Я хотел бы добавить к объяснению Шими, что еще одно ограничение синтаксиса varargs заключается в том, что vararg должен быть последним объявленным параметром.Итак, вы не можете сделать это:

void myMethod(String... values, int num);

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

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

Хорошим примером является String.format().Здесь переменные аргументы сопоставляются с заполнителями формата в первом аргументе.

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

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

Ожидаете ли вы, что вызывающий ваш метод будет иметь под рукой массив Foo?Затем используйте версию Foo[].Используйте вариант varargs, чтобы подчеркнуть возможность использования «кучки» Foo вместо массива.

Классическим примером varargs является строковый формат (в C#, не знаю, как он называется в Java):

string Format(string formatString, object... args)

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

С другой стороны, что-то вроде

string Join(string[] substrings, char concatenationCharacter)

использование массива вполне разумно.

Также обратите внимание, что вы можете иметь несколько параметров массива и только один параметр vararg в конце списка параметров.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top