С JLS 15.12.2.5 (выделение добавлено):
Если более одного метода-члена доступны и применимы к вызову метода, необходимо выбрать один предоставить дескриптор для отправки метода во время выполнения. В языке программирования Java используется правило, согласно которому выбирается наиболее конкретный c метод .
Неформальная интуиция заключается в том, что один метод более специфичен c, чем другой, если любой вызов обработанный первым методом может быть передан другому без ошибки времени компиляции.
Все, что может быть передано методу String
, также может быть передано методу Object
в то время как есть вещи, которые вы можете передать методу Object
, которые нельзя передать методу String
(например, new Object()
) (*); поэтому метод String
более специфичен c, так что это тот, который выбран.
(*) Это предложение важно: если вы заменили метод Object
, скажем, :
private static void doSomething(Integer s) {
тогда будут вещи, которые вы можете передать doSomething(String)
, которые вы не сможете передать doSomething(Integer)
; и были бы вещи, которые вы могли бы передать doSomething(Integer)
, которые вы не могли бы передать doSomething(String)
. В этом случае ни один из них не является более конкретным c, поэтому вызов метода будет считаться неоднозначным.