Помните, что литерал null
имеет тип "специальный нулевой тип", а не тип Object
Распространенным заблуждением является то, что литерал null
относится к типу Object
, что приводит людей к мысли, что ближайшая подходящая подпись - target(Object val, String chk)
.
Литерал null
на самом деле имеет тип "[специальный нулевой тип]" ( Спецификация языка Java (JLS) 4 ). Если бы возможно было определить такой метод, самое близкое совпадение было бы target([special null type] val, String chk)
.
Однако, поскольку такого метода нет (вы не могли его создать), компилятор ищет наиболее близкое совпадение с помощью подтипа ( JLS 15.12.2.2 ). Прямой супертип [специального нулевого типа] - это все ссылочные типы ( JLS 4.10.2 ) (например, String), а Object является супертипом String.
Возможно, более интуитивно понятный способ взглянуть на него - это интуитивное определение JLS для "наиболее конкретного метода" ( JLS 15.12.2.5 ):
"Неформальная интуиция заключается в том, что один метод более специфичен, чем
другой, если любой вызов, обработанный первым методом, мог быть передан
на другой без ошибки типа во время компиляции. "
Из двух методов, которым соответствует вызов target(null ,"Object")
, любой вызов
void target(String val, String chk)
может обрабатываться
void target(Object val, String chk)
настолько интуитивно void target(String val, String chk)
является «наиболее специфичным», который можно вызвать без ошибки типа.
См. JLS 15.12.2.5 о том, как формально определено «наиболее конкретное».