2013-04-02 40 views
5

Mã này:<? extends > Java cú pháp

List<? extends Reader> weirdList; 
weirdList.add(new BufferedReader(null)); 

có một lỗi biên dịch của

Phương pháp này thêm vào kiểu List không áp dụng cho các (capture # 1-of kéo dài Reader là gì?) đối số (BufferedReader)

Tại sao? BufferedReader mở rộng trình đọc, vậy tại sao không phải là "kết hợp"?

+2

có thể trùng lặp với [Câu hỏi WildCard Java Generics: Danh sách ] (http://stackoverflow.com/questions/5495383/java-generics-wildcard-question-list-extends-a) – yshavit

+0

(FWIW, những gì bạn muốn ở đây là 'Danh sách ', không phải 'Danh sách '.) –

Trả lời

3

Đối với biến bạn đã cho:

List<? extends Reader> weirdList; 

Tất cả các bài tập sau đây là hợp lệ:

weirdList = new ArrayList<Reader>(); 
weirdList = new ArrayList<FileReader>(); 
weirdList = new ArrayList<BufferedReader>(); 
weirdList = new ArrayList<InputStreamReader>(); 

Hy vọng rằng điều này giải thích lỗi biên dịch của bạn. Những gì bạn đang cố gắng có ý nghĩa nếu weirdList giữ giá trị loại ArrayList<BufferedReader>, nhưng không có ý nghĩa đối với giá trị loại ArrayList<FileReader>. Vì một biến kiểu List<? extends Reader> có thể giữ một giá trị của một trong hai loại (và nhiều hơn nữa!), Java gọi là một lỗi.

Generics trong Java rất khó để có được đầu của bạn xung quanh. Bạn có thể nghĩ loại List<? extends Reader> là chủ yếu hữu ích cho việc gán hoặc kiểu tham số trong các phương thức để chúng có thể chấp nhận nhiều loại khác nhau. Đối với "thường xuyên sử dụng", bạn có thể tốt hơn với một "trần" chung như List<Reader> hoặc thậm chí List<BufferedReader>.

6

Khi trình biên dịch xem <? extends Reader>, thì giả định rằng nó có thể là bất kỳ loại nào là hoặc mở rộng Reader. Nó có thể là cái gì đó không tương thích với BufferedReader, chẳng hạn như StringReader. Vì vậy, nếu loại chung trong định nghĩa lớp hiển thị trong tham số của một phương thức như add và loại cá thể có một cái gì đó như <? extends Something>, trình biên dịch phải không cho phép nó vì lý do an toàn loại. Trong ví dụ này, số có thểList<StringReader>, vì vậy bạn không thể thêm BufferedReader tại đây.

6

List<? extends Reader> weirdList có thể giữ tham chiếu đến bất kỳ loại List nào lưu trữ bất kỳ loại Reader nào. Vì vậy, nó có thể là

List<? extends Reader> weirdList1 = new ArrayList<BufferedReader>(); 
List<? extends Reader> weirdList2 = new ArrayList<FileReader>(); 

Nếu Java sẽ cho phép bạn thêm BufferedReader để weirdList1 nó cũng sẽ phải cho phép bạn thêm BufferedReader để weirdList2 (loại tài liệu tham khảo là như nhau) mà không phải là giả sử để xảy ra kể từ khi weirdList2 nên lưu trữ chỉ FileReader s.

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