Переменная аргумент, функция неоднозначность - PullRequest
7 голосов
/ 27 сентября 2010
   public static void main(String[] args) {
       System.out.println(fun(2,3,4));
     }
   static int fun(int a,int b,int c)
   {
     return 1;
   }
   static int fun(int ... a)
   {
     return 0;  
   }

Выход: 1

Вопрос: В вышеприведенном случае почему функция fun выбирает 1-ю функцию, а не вторую. На каком основании выполняется выбор, поскольку нет способа определить, какое удовольствие пользователь фактически хотел вызвать?

Ответы [ 4 ]

9 голосов
/ 27 сентября 2010

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

JLS не очень ясно объясняет это, но это в разделе 15.12..2.5 , часть, в которой говорится, что метод фиксированной арности более специфичен, чем другой метод, если выполняются определенные условия - и они делают в этом случае.В основном это более конкретно, потому что есть больше вызовов, которые будут действительными для метода varargs, так же, как если бы было то же количество параметров, но сами типы параметров были более общими.

3 голосов
/ 27 сентября 2010

Компилятор всегда выбирает точный метод, когда встречаются такие неоднозначности. В вашем сценарии func с тремя аргументами является более точным, чем переменные аргументы, один из которых называется.

РЕДАКТИРОВАТЬ: Отредактировано в соответствии с комментарием скита.

2 голосов
/ 27 сентября 2010

Если вы протестируете это выражение:

    System.out.println(fun(2,3,4));
    System.out.println(fun(2,3));
    System.out.println(fun(2,3,4,7));

Вывод будет

1
0
0

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

0 голосов
/ 02 марта 2015

Такое поведение позволяет разрешить два перегруженных вызова аргумента переменной:

addStates(String... states)
addStates(Enum... states)

Вызов addStates () создает проблему неоднозначности компиляции.Добавление в третий метод:

addStates(){
   addStates(new String[0]);
}

Это позволяет выбрать более конкретный третий метод addStates (), чтобы решить проблему неоднозначности из-за неуверенности, какой из методов параметра типа переменной вызывать.

...