В разрешении перегрузки используются 3 фазы ( JLS 15.2.2 ):
blockquote>
- Первая фаза (§15.12.2.2) выполняет разрешение перегрузки без разрешения преобразования бокса или распаковки или использования вызова метода переменной arity. Если на этом этапе не обнаружен какой-либо применимый метод, обработка продолжается до второй фазы.
- Вторая фаза (§15.12.2.3) выполняет разрешение перегрузки при разрешении бокса и распаковки, но все же исключает использование вызова метода переменной arity. Если на этом этапе не обнаружен какой-либо применимый метод, обработка продолжается до третьей фазы.
- Третья фаза (§15.12.2.4) позволяет комбинировать перегрузку с методами переменной arity, боксом и распаковкой.
В вашем примере оба метода являются методами переменной arity, поэтому применяется третья фаза.
Теперь, поскольку у нас есть два метода на выбор, мы ищем более конкретный метод.
JLS 15.12.2.5. Выбор наиболее конкретного метода говорит:
Если более чем один метод-член доступен и применим к вызову метода, необходимо выбрать один для предоставления дескриптора для запуска отправка времени. Язык программирования Java использует правило, в котором выбран наиболее специфический метод.
...
Один применимый метод m1 более конкретный, чем другой применимый метод m2, для вызова с аргументом выражения e1, ..., ek, если выполнено одно из следующих утверждений:
...
m2 не является общим, m1 и m2 применимы при вызове переменной arity и где первые k переменных параметров arity параметров m1 являются S1, ..., Sk и первыми k переменными параметрами параметра arity m2 являются T1, ..., Tk, тип Si более специфичен, чем Ti для аргумента ei для всех i (1 ≤ i ≤ k). Кроме того, если m2 имеет k + 1 параметров, то k + 1'th переменный параметр параметра arity m1 является подтипом k + 1-го параметра параметра переменной arity m2.
blockquote>В вашем случае у вас есть два не общих метода, которые применимы при вызове переменной arity (т.е. оба имеют varargs). Чтобы один из методов был выбран, когда вы вызываете
method(1)
, один из них должен быть более конкретным, чем другой. В вашем случае каждый метод имеет только один параметр и для одного из них должен быть более конкретным, чем для другого, тип этого одного параметра должен быть подтипом параметра другого метода.Поскольку
int
не является подтипомInteger
, аInteger
не является подтипомint
, ни один из ваших методов не является более конкретным, чем другой. Следовательно, ошибкаThe method method(int[]) is ambiguous for the type Test
.Пример, который будет работать:
public static void method(Object... x) { System.out.println("varargs"); } public static void method(Integer... x) { System.out.println("single"); }
Поскольку
Integer
является подтипомObject
, будет выбран второй метод когда вы вызываетеmethod(1)
.