Це слабкість у механізмі посилення типу компілятора. Для того, щоб зробити висновок про тип u
лямбда, потрібно встановити цільовий тип лямбда. Це здійснюється наступним чином. userList.sort()
очікує аргументу типу Comparator<User>
. У першому рядку Comparator.comparing()
потрібно повернутися Comparator<User>
. Це означає , що Comparator.comparing()
потребує Function
тому , що приймає User
аргумент. Таким чином, лямбда на першому рядку u
повинна бути типу User
і все працює.
У другому та третьому рядках введення цілі порушується наявністю виклику до reversed()
. Я не зовсім впевнений, чому; як приймач і тип повертається reversed()
є Comparator<T>
так здається, має бути розповсюджується назад в приймач цільового типу, але це не так . (Як я вже казав, це слабкість.)
У другому рядку посилання на метод забезпечує додаткову інформацію про тип, яка заповнює цей проміжок. Ця інформація відсутня в третьому рядку, тому компілятор підводить u
до Object
висновку (резервний висновок в останню інстанцію), який не вдається.
Очевидно, що якщо ви можете скористатися посиланням на метод, зробіть це, і воно буде працювати. Іноді ви не можете використовувати посилання на метод, наприклад, якщо ви хочете передати додатковий параметр, тому вам доведеться використовувати лямбда-вираз. У такому випадку ви вкажете явний тип параметра в лямбда:
userList.sort(Comparator.comparing((User u) -> u.getName()).reversed());
Можливо, компілятор може бути вдосконалений, щоб охопити цю справу в майбутньому випуску.