Метод может быть
перегружен различными параметрами – в классе могут существовать несколько разных методов с одинаковым названием. При вызове такого метода выбор конкретного варианта происходит на этапе компиляции (раннее связывание). В деталях алгоритм выбора перегруженного метода описан в
спецификации.
Выбор происходит в два шага. На первом выбирается
одна из трех фаз – множество подходящих методов.
1. Методы, в которые переданные параметры подходят по типу либо как есть, либо с применением расширения (upcasting)
примитивов или
ссылочных типов, исключая
vararg-параметры.
2. Если в фазе 1 подходящих методов не нашлось, к ее условиям добавляются возможность
боксинга/анбоксинга параметров. Обратите внимание, в комбинации работает только боксинг+расширение, но не наоборот.
3. Если и для фазы 2 нет удовлетворительных сигнатур, к условиям поиска подключаются vararg-параметры.
В случае, когда ни один метод не нашелся ни в одной фазе, компиляция завершается ошибкой.
Когда в
фазе имеется несколько подходящих методов, используется
наиболее специфичный среди них (но только в рамках данной фазы!).
Метод A считается более специфичным чем B, когда
типы параметров одного метода – подтипы типов параметров другого. То есть любые возможные значения аргументов A подошли бы и для B, но не наоборот.
В условии специфичности говорится о типах параметров метода, а не о типах передаваемых значений. Так что боксинг/анбоксинг не учитывается, и метод с параметром
int не считается более специфичным, чем с параметром
Object (в отличие от
Integer). Хотя, целое число можно передавать и как
Object, и как
Integer.
Подробное объяснение.
Когда среди методов невозможно выделить один наиболее специфичный, происходит ошибка компиляции.