Đây là một điểm yếu trong cơ chế truyền thông kiểu của trình biên dịch. Để suy ra loại u
trong lambda, loại đích cho lambda cần phải được thiết lập. Điều này được thực hiện như sau. userList.sort()
đang mong đợi một đối số thuộc loại Comparator<User>
. Trong dòng đầu tiên, Comparator.comparing()
cần phải trả lại Comparator<User>
. Điều này ngụ ý rằng Comparator.comparing()
cần Function
phải có một User
đối số. Vì vậy, trong lambda ở dòng đầu tiên, u
phải là loại User
và mọi thứ hoạt động.
Trong dòng thứ hai và thứ ba, việc nhập mục tiêu bị gián đoạn bởi sự hiện diện của lệnh gọi tới reversed()
. Tôi không hoàn toàn chắc chắn tại sao; cả kiểu nhận và kiểu trả về reversed()
đều Comparator<T>
như vậy nên có vẻ như kiểu đích nên được truyền ngược lại cho người nhận, nhưng không phải vậy. (Như tôi đã nói, đó là một điểm yếu.)
Trong dòng thứ hai, tham chiếu phương thức cung cấp thông tin loại bổ sung lấp đầy khoảng trống này. Thông tin này không có trong dòng thứ ba, do đó, trình biên dịch suy luận u
là Object
(dự phòng suy luận của phương án cuối cùng), không thành công.
Rõ ràng nếu bạn có thể sử dụng tham chiếu phương thức, hãy làm điều đó và nó sẽ hoạt động. Đôi khi bạn không thể sử dụng tham chiếu phương thức, ví dụ: nếu bạn muốn truyền một tham số bổ sung, vì vậy bạn phải sử dụng biểu thức lambda. Trong trường hợp đó, bạn sẽ cung cấp một loại tham số rõ ràng trong lambda:
userList.sort(Comparator.comparing((User u) -> u.getName()).reversed());
Có thể trình biên dịch được cải tiến để giải quyết trường hợp này trong một bản phát hành trong tương lai.