Как упоминалось ранее, разрешение перегрузки выполняется во время компиляции.
У Java Puzzlers есть хороший пример для этого:
Головоломка 46: Дело о сбивающем с толку конструкторе
Эта головоломка представляет вам двух сбивающих с толку конструкторов. Основной метод вызывает конструктор, но какой? Результат работы программы зависит от ответа. Что печатает программа, и это вообще законно?
public class Confusing {
private Confusing(Object o) {
System.out.println("Object");
}
private Confusing(double[] dArray) {
System.out.println("double array");
}
public static void main(String[] args) {
new Confusing(null);
}
}
Решение 46: случай сбивающего с толку конструктора
... Процесс разрешения перегрузки Java состоит из двух этапов. На первом этапе выбираются все доступные и применимые методы или конструкторы. На втором этапе выбирается наиболее конкретный из методов или конструкторов, выбранных на первом этапе. Один метод или конструктор менее специфичен, чем другой, если он может принимать любые параметры, переданные другому [JLS 15.12.2.5].
В нашей программе оба конструктора доступны и применимы. Конструктор
Confusing (Object) принимает любой параметр, переданный в Confusing (double []) , поэтому
Confusing (Object) менее конкретен. (Каждый двойной массив является объектом , но не каждый объект является двойным массивом .) Поэтому наиболее конкретным конструктором является Confusing (double []) , который объясняет вывод программы.
Такое поведение имеет смысл, если вы передаете значение типа double [] ; это нелогично, если вы передадите null . Ключ к пониманию этой загадки заключается в том, что тест, для которого метод или конструктор наиболее специфичен, не использует фактические параметры : параметры, появляющиеся в вызове. Они используются только для определения возможных перегрузок. Как только компилятор определяет, какие перегрузки применимы и доступны, он выбирает наиболее конкретную перегрузку, используя только формальные параметры: параметры, указанные в объявлении.
Чтобы вызвать конструктор Confusing (Object) с параметром null , напишите new Confusing ((Object) null) . Это гарантирует, что применим только Confusing (Object) . В более общем смысле, чтобы заставить компилятор выбрать конкретную перегрузку, приведите фактические параметры к объявленным типам формальных параметров.