Các JLS SE 8 nói tại (§15.2):
Khi một số thành ngữ xuất hiện trong những bối cảnh nhất định, họ được coi là biểu poly. Các hình thức sau các biểu thức có thể biểu poly:
biểu thức trong ngoặc đơn (§15.8.5)
biểu thức tạo dụ Class (§15.9)
biểu Phương pháp gọi (§15.12)
Biểu thức tham chiếu phương thức (§15.13)
biểu thức có điều kiện (§15.25)
Lambda biểu thức (§15.27)
Vì vậy, từ phần này của spec rõ ràng là biểu thức có điều kiện, các nhà điều hành ternary, có thể được coi biểu poly. Nhưng không phải tất cả các biểu thức có điều kiện đều có thể được coi là biểu thức poly, chỉ tham chiếu biểu thức có điều kiện theo (§15.25). Điều kiện mà một biểu thức điều kiện tham khảo có thể được coi là một biểu hiện nhiều được làm rõ tại (§15.25.3):
Một tài liệu tham khảo biểu thức điều kiện là một biểu thức nhiều nếu nó xuất hiện trong bối cảnh chuyển nhượng hoặc một bối cảnh gọi (§5.2 §5.3.). Nếu không, nó là một biểu thức độc lập.
Trong trường hợp biểu thức điều kiện nhiều tài liệu tham khảo xuất hiện trong một bối cảnh của một loại đặc biệt với loại mục tiêu T, biểu thức toán hạng thứ hai và thứ ba của nó tương tự xuất hiện trong một bối cảnh cùng loại với loại mục tiêu T.
Loại một biểu thức điều kiện tham chiếu poly là giống như kiểu đích của nó.
Kiểm tra xem trong ví dụ của bạn biểu thức điều kiện xuất hiện trong một bối cảnh chuyển nhượng vì theo (§14.17):
Khi một tuyên bố trở lại với một biểu thức xuất hiện trong một tuyên bố phương pháp, khái niệm phải được chuyển nhượng (§ 5.2) cho kiểu trả về đã khai báo của phương thức, hoặc xảy ra lỗi biên dịch.
Vì vậy, vào cuối ngày, điều này có nghĩa là gì? Điều này ngụ ý rằng khi các biểu thức có điều kiện là các biểu thức poly, kiểu đích được "đẩy xuống" cho mỗi toán hạng. Bằng cách này trình biên dịch có thể thuộc tính từng phần của điều kiện, so với mục tiêu. Trong trường hợp của bạn, mục tiêu là List<String>
. Nếu chúng tôi kiểm tra định nghĩa của phương pháp emptyList() ta có:
@SuppressWarnings("unchecked")
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
Vì vậy, với mục tiêu List<String>
, trình biên dịch có thể suy ra rằng T == String và mã được chấp nhận.
http://stackoverflow.com/questions/21258160/why-is-javas-type-inference-so-weak – assylias
Toán tử bậc ba có vấn đề kết hợp với trả về chung, điều đó được biết rõ. Chỉ định thông số loại một cách rõ ràng. – qqilihq