Không, nó không chỉ đọc ... mặc dù đó thường là ý định.
Cho đối tượng List<? extends Number>
, trình biên dịch converts loại của nó là List<X>
trong đó X là một loại phụ không xác định của Số. Do đó, đối tượng có phương thức add(X)
. Chúng ta có thể gọi phương thức với đối số X
... ví dụ: null
.
Và kể từ get()
lợi nhuận X
, chúng ta cũng có thể gọi add()
với một giá trị từ get()
.... Trực tiếp gọi list.add(list.get(i))
sẽ không làm việc, mặc dù nó có ý nghĩa. Chúng tôi sẽ cần một chút helper.
Ví dụ cổ điển là Collections.reverse(List<? extends Object> list)
. Phương pháp này sẽ sửa đổi list
, mặc dù ký tự đại diện.
Bạn cũng có thể gọi các phương pháp đột biến như clear()
, tất nhiên, trên bất kỳ danh sách nào.
Điều đó đang được nói, ký tự đại diện thực sự là chủ yếu để sử dụng tại chỗ variance, và thường xuyên nhất, nó truyền đạt ý định từ nhà thiết kế API cho dù một loại tham số là dành cho trong hoặc ra. Ví dụ: bằng cách khai báo List<? super/extends Foo>
, API thể hiện rằng nó có ý định tiêm T vào hoặc, lấy T ra khỏi, danh sách.
Đó là quan niệm sai lầm rằng ký tự đại diện chỉ đọc/ghi. Nhưng quan niệm sai lầm này hoạt động trong hầu hết các trường hợp sử dụng. Và càng có nhiều người có quan niệm sai lầm này, càng có nhiều nó trở thành một ước ...
xem bài viết của tôi trên wildcard - http://bayou.io/draft/Capturing_Wildcards.html
Tôi không biết, lưu ý rằng nums.add ((Số) new Double (3.14)); kết quả trong lỗi: Phương thức thêm (capture # 1-of? extends Number) trong danh sách loại không áp dụng cho các đối số (Số) –
Xem câu hỏi này: http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs – Natix
đây là một quan niệm sai lầm rất phổ biến; nhưng quan niệm hoạt động trong hầu hết các trường hợp :) – ZhongYu