Массивы объектов в сигнатурах методов - PullRequest
5 голосов
/ 06 октября 2008

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

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

и

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

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

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

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

Ответы [ 4 ]

12 голосов
/ 06 октября 2008

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

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

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

3 голосов
/ 06 октября 2008

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

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

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

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

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

1 голос
/ 06 октября 2008

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

0 голосов
/ 06 октября 2008

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

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

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

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

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

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

string Join(string[] substrings, char concatenationCharacter)

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

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

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