Це слабкість у механізмі посилення типу компілятора. Для того, щоб зробити висновок про тип 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());
Можливо, компілятор може бути вдосконалений, щоб охопити цю справу в майбутньому випуску.