2014-06-20 23 views
7

Trước Java 7 cú pháp dưới đây được sử dụng để tạo một ArrayList,Sử dụng toán tử kim cương trong Java 7

ArrayList<Integer> ints = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7)); 

Nhưng kể từ Java 7 chúng ta có thể bỏ qua các loại generic trong ví dụ nhà xây dựng,

ArrayList<Integer> ints = new ArrayList<>(Arrays.asList(1,2,3,4,5,6,7)); 

nhưng khi tôi cố gắng làm một cái gì đó như thế nào,

ArrayList<Number> nums = new ArrayList<>(Arrays.asList(1,2,3,4,4,5.5,6.6,7.7)); 

tôi nhận được một lỗi, nhưng khi tôi đề cập đến các loại generic trên bên phải tức là,

ArrayList<Number> nums = new ArrayList<Number>(Arrays.asList(1,2,3,4,5.5,6.6,7.7)); 

Mã hoạt động hoàn hảo. Điều gì có thể là lý do đằng sau điều này?

Cảm ơn trước.

+0

Tôi không thể kéo các đoạn cụ thể từ JLS thay đổi giữa Java 7 và 8 để hỗ trợ điều này, vì vậy đây là nhận xét, nhưng nếu bộ nhớ phục vụ Java 8 mở rộng các loại suy luận có thể được thực hiện, tôi tin cho phép tìm kiếm siêu kiểu cũng như/hoặc bằng cách sử dụng ngữ cảnh bổ sung. Đoạn mã thứ ba của bạn biên dịch mà không có khiếu nại trong Java 8. – awksp

Trả lời

4

Arrays.asList là một phương pháp chung chung, do kỹ thuật, nó có thể được gọi là:

Arrays.<Number> asList(1, 2, 3); 

Ngay cả trước khi Java 7, ngôn ngữ có thể làm một số suy luận hạn chế để loại bỏ này khi phía bên tay trái đã được biết đến, như trong

final List<Number> nums = Arrays.asList(1, 2, 3); 

Dường như bạn đã tình cờ gặp trường hợp cạnh mà không thể kết hợp thành công hai loại suy luận, nơi suy luận kim cương và suy luận phương pháp chung không hòa hợp. Tôi cũng chắc chắn là the JLS sheds more light on this nếu bạn đang đào sâu nó.

3

Java Generics là Invariant trong khi mảng là Covariant.

Nếu Generics trong Java là hiệp biến, nếu A là một subtype của B, sau đó List[A] là một subtype của List[B]. Nhưng nó không phải là trường hợp trong Java. (Scala có thực hiện hiệp phương sai. Trong Scala, nếu B kéo dài A, sau đó mở rộng List[B]List[A])

Nhưng String[] là subtype của Object[]

Do đó một ArrayList<Double> không thể được đúc để một ArrayList<Number> như trong trường hợp của bạn.

Các vấn đề liên quan