Ответ 1
Правила выбора правильного перегруженного метода следующие:
- Примитивное расширение использует наименьший возможный аргумент метода
- Тип обтекателя не может быть расширен до другого типа Wrapper
- Вы можете вставить из int в Integer и расширить до Object, но не до Long
- Расширение бьет Бокс, Бокс побеждает Вар-Аргса.
- Вы можете вставить Box, а затем Widen (int может стать объектом через Integer)
- Вы не можете Widen, а затем Box (An int не может стать длинным)
- Вы не можете комбинировать var-args с расширением или боксом
Посмотрите на это последнее правило. Вы не можете комбинировать расширение или бокс с аргументами переменной длины. Это означает, что типы нельзя манипулировать каким-либо образом, и вам нужно выполнить сравнение как есть. int
и long
можно сравнить, без проблем, и компилятор может вывести, что int
является меньшим из двух. Согласно первому правилу, он будет использоваться для наименьшего аргумента метода, поэтому он разработал правильный (и только) маршрут к методу.
Однако, когда вы переходите к boolean
и int
, между ними нет метода сравнения из-за сильной типизации Java. Не имея знания о том, какой тип является наименьшим, компилятор абсолютно не знает, какой метод вы имеете в виду.
Более визуальный пример
Позвольте сделать шаг за шагом с точки зрения компилятора. Во-первых, с int
и long
.
int и long
Шаг 1 - Проверка соответствия параметров любым аргументам, и если да, то какой из них соответствует точно
Ну, varargs
означает, что вы можете передать 0
во многие аргументы. В этом случае вы решили передать аргументы 0
, поэтому ваш вызов соответствует типу int
и типу long
.
Шаг 2 - попытка автобокса или расширения. Это должно помочь ему разобраться, какой из них нужно для
Вы используете varargs, поэтому компилятор знает, что он не может этого сделать, в соответствии с окончательным правилом.
Шаг 3 - Попытка выяснить, какой тип наименьший
Компилятор может сравнить тип int
с типом long
. Из этого следует, что int
является наименьшим типом.
Шаг 4 - Вызов
С учетом того, что int
является наименьшим типом, он затем передает значение методу для выполнения.
Хорошо, а теперь сделаем то же самое с boolean
и int
.
boolean и int
Шаг 1 - Проверка соответствия параметров любым аргументам, и если да, то какой из них соответствует точно
Та же история. Вы ничего не передали, так что оба аргумента совпадают.
Шаг 2 - попытка автобокса или расширения. Это должно помочь ему разобраться, какой из них нужно для
Как и выше, вам не разрешено делать это, потому что вы использовали varargs.
Шаг 3 - Попытка выяснить, какой тип наименьший
Это ключевое различие. Здесь типы не сопоставимы. Это означает, что компилятор не знает, какой метод вы хотите вызывать по вашим параметрам или по наименьшему типу. Ergo, он не смог выработать правильный маршрут.
Шаг 4 - Вызов
Без знания того, какой метод вызывать, он не может продолжить выполнение и выбрасывает соответствующее исключение.