2013-07-02 40 views
5

tôi đã tự hỏi tại sao các bit mã sau đây không làm việc:Generics <? super> wildcard

Collection <? super String> col = new ArrayList<String>(); 
col.add(new Object());// does not compile 
col.add("yo!");// compiles indeed; 

Nếu loại là <? super String> nó có thể chứa bất cứ điều gì đó là siêu String (String bao gồm) không?

+4

' 'chỉ có thể thêm Chuỗi. 'Object' có thể không phải là String .. Cố gắng làm:' Object myObj = new String(); 'và nó sẽ hoạt động. – Maroun

+1

Không, mọi thứ ** mở rộng ** Chuỗi. Nó có nghĩa là *? mà siêu là String *. – m0skit0

+0

@ m0skit0 đó là nơi tôi đã bối rối. Cảm ơn. – Rollerball

Trả lời

15

Collection<? super String>, truy cập trực giác của bạn, không có nghĩa là "bộ sưu tập chứa đối tượng thuộc loại String hoặc siêu kiểu của nó". Nó có nghĩa là "col sẽ là một bộ sưu tập chứa một số loại nhất định, mà chính nó là String hoặc siêu kiểu của nó" (chẳng hạn như Object, Serializable hoặc CharSequence).

Cách tốt nhất để suy nghĩ về Collection<? super String> là nó không phải là một loại, như bạn đã quen với Java, nhưng là một mẫu đối với loại kết hợp cụ thể nào.

Bây giờ, điều duy nhất bạn có thể thêm vào bộ sưu tập phù hợp với mẫu trên là String hoặc lớp con của nó (nếu có). Hoàn toàn trái ngược với những gì bạn mong đợi, phải không? Đó là Generics cho bạn.

+0

Heh, nice. Để hoàn thành ví dụ của bạn, một 'Chuỗi' có thể được đặt vào một' Bộ sưu tập '... –

+0

Cảm ơn bạn đã giải thích rõ ràng Marko, đây không phải là lần đầu tiên câu trả lời của bạn giúp tôi –

3

Với Collection <? super String>, chúng tôi không biết những gì loại của các đối tượng nó chứa chính xác, nhưng chúng ta biết rằng nó phải là một bộ sưu tập của một trong hai String hoặc một số lớp cha của String, tức là nó là an toàn để đặt một String vào nhưng không nhất thiết phải là Object. Ngược lại đối với các phương thức mà lấy thứ ra khỏi bộ sưu tập (ví dụ: khi lặp lại), chúng tôi không thể chắc chắn chúng tôi sẽ nhận lại chuỗi.

Mặt khác với Collection<? extends Foo> chúng tôi biết đó là một bộ sưu tập của một cái gì đó là một trong hai Foo hoặc một số lớp con của Foo, vì vậy chúng ta có thể an toàn mất một cái gì đó từ bộ sưu tập và biết nó sẽ được chuyển nhượng để Foo, nhưng chúng ta có thể 't đặt bất kỳ thứ gì vì chúng tôi không có cách nào biết được loại nào sẽ an toàn.

+0

Giải thích tuyệt vời, tôi hiểu rõ hơn bây giờ ~ – bean

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