Что нужно помнить о выводе типа в цепочках вызовов, так это то, что вывод типа выполняется по мере продвижения по цепочке: если у вас есть a().b()
:
- Вывод типа выполняется для
a()
first; - Затем выводится тип для
a().b()
Итак:
parent(makeParent())
: тип makeParent()
выводится в соответствии с тем, что совместимо с параметром parent()
. Поскольку это будет принимать только Parent<String>
, это предполагаемый тип.
child(makeParent().child())
: предполагается тип makeParent()
; но нет никаких ограничений на тип (это не параметр внешнего child
), поэтому предполагается, что он равен Parent<Object>
; тогда типом makeParent().child()
будет Child<Object>
, что несовместимо с типом параметра child
, отсюда и ошибка компилятора.
Досадно, что Java не 'Не откладывайте вывод типа makeParent()
до тех пор, пока он не получит больше информации, а именно тот факт, что makeParent().child()
должен быть совместим с каким-то конкретным типом.
Я полагаю, это сделано для ограничения сложности вывода : Я могу представить себе ситуацию, когда может потребоваться решить некоторый до неприличия сложный набор ограничений вывода типов.