? extends HasWord
có nghĩa là "Một lớp / giao diện mở rộng HasWord
." Nói cách khác, HasWord
chính nó hoặc bất kỳ đứa con nào của nó ... về cơ bản là bất cứ thứ gì có thể hoạt động cùng với instanceof HasWord
cộng null
.
Nói một cách kỹ thuật hơn, ? extends HasWord
là một ký tự đại diện giới hạn, được nêu trong Mục 31 của Phiên bản Java hiệu quả thứ 3 , bắt đầu từ trang 139. Chương tương tự từ Phiên bản 2 có sẵn trực tuyến dưới dạng PDF ; phần trên các ký tự giới hạn là Mục 28 bắt đầu từ trang 134.
Cập nhật: Liên kết PDF đã được cập nhật kể từ khi Oracle gỡ bỏ nó một lúc trước. Bây giờ nó chỉ đến bản sao được lưu trữ bởi Trường Kỹ thuật Điện tử và Khoa học Máy tính của Đại học Queen Mary, London.
Cập nhật 2: Hãy đi sâu vào chi tiết hơn một chút về lý do tại sao bạn muốn sử dụng ký tự đại diện.
Nếu bạn khai báo một phương thức mà chữ ký của bạn mong đợi bạn truyền vào List<HasWord>
, thì điều duy nhất bạn có thể truyền vào là a List<HasWord>
.
Tuy nhiên, nếu nói chữ ký là List<? extends HasWord>
sau đó bạn có thể vượt qua trong một List<ChildOfHasWord>
thay thế.
Lưu ý rằng có một sự khác biệt tinh tế giữa List<? extends HasWord>
và List<? super HasWord>
. Như Joshua Bloch đã nói: PECS = nhà sản xuất mở rộng, siêu người tiêu dùng.
Điều này có nghĩa là nếu bạn chuyển qua một bộ sưu tập mà phương thức của bạn lấy dữ liệu từ đó (tức là bộ sưu tập đang tạo ra các phần tử cho phương thức của bạn để sử dụng), bạn nên sử dụng extends
. Nếu bạn chuyển qua một bộ sưu tập mà phương thức của bạn thêm dữ liệu vào (tức là bộ sưu tập đang tiêu thụ các yếu tố mà phương thức của bạn tạo ra), thì nó nên sử dụng super
.
Điều này nghe có vẻ khó hiểu. Tuy nhiên, bạn có thể nhìn thấy nó trong List
's sort
lệnh (mà chỉ là một shortcut lên phiên bản hai arg của Collections.sort). Thay vì lấy một Comparator<T>
, nó thực sự mất một Comparator<? super T>
. Trong trường hợp này, Trình so sánh đang sử dụng các phần tử của List
thứ tự để sắp xếp lại Danh sách.