Przeczytałem książkę O'Reilly, dzięki której poznałem zasadę wstępu .
- Użyj
extends
symbolu wieloznacznego, gdy otrzymujesz wartości tylko ze struktury.- Użyj
super
symbolu wieloznacznego, gdy umieszczasz tylko wartości w strukturze.- I nie używaj symbolu wieloznacznego, gdy oboje chcecie pobrać i wstawić z / do struktury.
Wyjątki to:
Nie możesz umieścić niczego w typie zadeklarowanym za pomocą
extends
symbolu wieloznacznego, z wyjątkiem wartościnull
, która należy do każdego typu referencyjnego.Nie można uzyskać niczego z typu zadeklarowanego za pomocą
super
symbolu wieloznacznego, z wyjątkiem wartości typeObject
, która jest nadtypem każdego typu referencyjnego.
Czy ktoś może mi pomóc zgłębić tę zasadę? Jeśli to możliwe, ułóż je hierarchicznie.
Odpowiedzi:
Rozważ kilka bananów. Chodzi o to
Collection<? extends Fruit>
, że jest to zbiór określonego rodzaju owoców - ale nie wiesz (z tej deklaracji), jakiego rodzaju jest to zbiór. Możesz zdobyć z niego przedmiot i wiedzieć, że na pewno będzie to owoc, ale nie możesz do niego dodać - możesz próbować dodać jabłko do kiści bananów, co z pewnością byłoby złe. Państwo może dodaćnull
do niej, jak to będzie ważna wartość dla dowolnego rodzaju owoców.Rozważmy teraz miskę z owocami. To jest a
Collection<? super Banana>
, w tym sensie, że jest to zbiór pewnego typu „większy niż”Banana
(na przykładCollection<Fruit>
lubCollection<TropicalFruit>
). Zdecydowanie możesz dodać do tego banana, ale jeśli wyjmiesz przedmiot z miski, nie wiesz, co otrzymasz - może to nie być banan. Wszystko, co na pewno wiesz, to to, że będzie to ważne (prawdopodobnienull
)Object
odniesienie.(Ogólnie rzecz biorąc, w przypadku pytań ogólnych w języku Java, często zadawane pytania dotyczące generycznych języków Java to doskonały zasób, który zawiera odpowiedzi na prawie wszystko związane z typami generycznymi, z którymi prawdopodobnie się zetkniesz).
źródło
Collection<? extends Fruit>
właśnie z tego powodu i musiałbyś jawnie rzutować wynik pobierania elementu, właśnie z tych powodów.Collection<? extends Person>
(lub bardziej prawdopodobnie tylkoIterable<? extends Person>
, ale ...). Kod tworzący tę kolekcję może wymagać, aby był to kodCollection<Employee>
, ale kod konsumujący nie.