Ответ 1
Это слабость в методе определения типа компилятора. Чтобы вывести тип u
в лямбда, необходимо установить тип цели для лямбды. Это выполняется следующим образом. userList.sort()
ожидает аргумент типа Comparator<User>
. В первой строке Comparator.comparing()
необходимо вернуть Comparator<User>
. Это означает, что Comparator.comparing()
требуется a Function
, который принимает аргумент User
. Таким образом, в лямбда на первой строке u
должен иметь тип User
и все работает.
Во второй и третьей строках целевой ввод прерывается присутствием вызова reversed()
. Я не совсем понимаю, почему; как приемник, так и тип возврата reversed()
равны Comparator<T>
, поэтому кажется, что целевой тип должен быть передан обратно в приемник, но это не так. (Как я уже сказал, это слабость.)
Во второй строке ссылка на метод предоставляет дополнительную информацию о типе, которая заполняет этот пробел. Эта информация отсутствует в третьей строке, поэтому компилятор выводит u
на Object
(отступ от последней попытки), который не работает.
Очевидно, что если вы можете использовать ссылку на метод, сделайте это, и он будет работать. Иногда вы не можете использовать ссылку на метод, например, если вы хотите передать дополнительный параметр, поэтому вам нужно использовать выражение лямбда. В этом случае вы должны указать явный тип параметра в лямбда:
userList.sort(Comparator.comparing((User u) -> u.getName()).reversed());
Возможно, возможно, что компилятор будет расширен, чтобы охватить этот случай в будущей версии.