Проблема в том, что является неоднозначным.
doIt(1, 2);
может быть вызовом doIt(int ...)
или doIt(double ...)
. В последнем случае целочисленные литералы будут повышены до double
значений.
Я почти уверен, что в спецификации Java говорится, что это неоднозначная конструкция, и компилятор просто следует правилам, установленным в спецификации. (Я должен исследовать это дальше, чтобы быть уверенным.)
РЕДАКТИРОВАТЬ - соответствующая часть JLS - " 15.12.2.5 Выбор наиболее специфического метода ", но это вызывает у меня головную боль.
Я думаю, что причина в том, что void doIt(int[])
не более конкретен (или наоборот), чем void doIt(double[])
, потому что int[]
не является подтипом double[]
(и наоборот). Поскольку две перегрузки одинаково специфичны, вызов неоднозначен.
В отличие от этого void doItAgain(int)
является более конкретным, чем void doItAgain(double)
, поскольку int
является подтипом double
в соответствии с JLS. Следовательно, вызов doItAgain(42)
не является двусмысленным.
РЕДАКТИРОВАТЬ 2 - @finnw прав, это ошибка. Рассмотрим эту часть 15.12.2.5 (отредактирован для удаления неприменимых случаев):
Один переменный метод члена арности с именем m является более конкретным , чем другой метод переменного члена арности с тем же именем, если:
Один метод-член имеет n параметров, а другой - k параметров, где n ≥ k. Типы параметров первого метода-члена: T1,. , , , Tn-1, Tn [], типами параметров другого метода являются U1,. , , , Великобритания-1, Великобритания. Пусть Si = Ui, 1 <= i <= k. Тогда: </p>
- для всех j от 1 до k-1, Tj <: Sj и </li>
- для всех j от k до n, Tj <: Sk </li>
Примените это к случаю, когда n = k = 1, и мы увидим, что doIt(int[])
более конкретно, чем doIt(double[])
.
На самом деле, существует отчет об ошибке для этого , и Sun признает, что это действительно ошибка, хотя они расценили ее как "очень низкую" . Ошибка помечена как исправленная в Java 7 (b123).