2013-07-24 11 views
25

Więc szukałem na niektóre kodu Java i natknęliśmy się na:Co oznacza mówienie <? rozciąga SomeObject> zamiast <SomeObject>

List<? extends SomeObject> l; 

zasadzie lista ta akceptuje wszystkie obiekty, które są pewnego rodzaju SomeObject - SomeObject sam lub jego spadkobierców. Ale według polymophism, to spadkobiercy mogą również być seens jak SomeObject, więc to będzie działać jak dobrze:

List<SomeObject> l; 

Więc dlaczego ktoś miałby używać pierwszą opcję, gdy druga jest jasno określony i praktycznie identyczne?

+7

ta jest dobrze wyjaśnione w samouczku Java: http: //docs.oracle.com /javase/tutorial/extra/generics/wildcards.html –

Odpowiedz

27
List<SomeObject> l; 

W tym nie można powiedzieć List<SomeObject> l = new ArrayList<SubClassOfSomeObjectClass>; (niedozwolone) wheres dla

List<? extends SomeObject> l; 

można powiedzieć

List<? extends SomeObject> l = new ArrayList<SubClassOfSomeObject>; (dozwolone)

Należy jednak pamiętać, że w List<? extends SomeObject> l = new ArrayList<SubClassOfSomeObject>; ty nie może dodać coś do listy l bo? reprezentuje nieznaną klasę (Z wyjątkiem zerowego kursu).

Aktualizacja: Na pytanie w komentarzu What could I possibly do with a list if I cannot add anything to it?

Rozważmy teraz przypadek, w którym trzeba napisać funkcję, aby wydrukować listę, ale umysł trzeba tylko zaakceptować Lista posiadającą przedmioty, które są podklasy twojego SomeObject. W tym przypadku, jak już wspomniano powyżej nie można używać

public void printList(List<SubClassOfSomeObjectClass> someList)

Więc co byś zrobił? Można by zrobić coś takiego

public void printList(List<? extends SomeObject> someList) { 
     for(SomeObject myObj : someList) { 
      //process read operations on myObj 
     } 
+1

Czy możesz wyjaśnić 2 rzeczy: Co mogę zrobić z listą, jeśli nie mogę nic dodać? Jakie jest znaczenie klasy podanej w konstruktorze wewnątrz < > –

+0

Proszę odnieść się do poniższych dwóch linków (Wildcards: bardzo pięknie wyjaśnione) http://docs.oracle.com/javase/tutorial/extra/generics/subtype.html i http://docs.oracle.com/javase/tutorial/ extra/generics/wildcards.html –

+0

@ OrCy ngiser 'Co mógłbym zrobić z listą, jeśli nie mogę nic do niej dodać? Czasami po prostu chcesz przeczytać/użyć zawartości jakiegoś kontenera bez modyfikowania go. 'Jakie jest znaczenie klasy podanej w konstruktorze wewnątrz <>' nie wiesz, o co pytasz. Po prostu jest to rodzaj ogólny. Więcej informacji [tutaj] (http://docs.oracle.com/javase/tutorial/java/generics/). Jeśli pytasz o '<>' spójrz na [tutaj] (http://stackoverflow.com/q/4166966/1393766) i [tutaj] (http://docs.oracle.com/javase/7/ docs/technotes/guides/language/type-in-ferencja-generic-instance-creation.html) – Pshemo

2

List<? extends SomeObject> l; nie przyjmuje new SomeObject() , ale robi to List<SomeObject> l;.

co także nie działa: List<SomeObject> l = new ArrayList<SubTypeOfSomeObject>()

co działa: List<? extends SomeObject> l = new ArrayList<SubTypeOfSomeObject>()

-2

jako pierwszą odpowiedź,

List<? extends SomeObject> l; 

moszcz zawiera Obiekt, który dziedziczą od SomeObject, nie jakiś bezpośredni SomeObject.

+10

To źle, ta lista może również zawierać SomeObject. – assylias

4

Kluczowym odsyłaczem do przeczytania jest http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html, który wyjaśnia szczegółowo wieloznaczny symbol wieloznaczny.

Numer List<SomeObject> nie jest taki sam jak List<? extends SomeObject>.Przestrzegać następujących

List<Object> x = new ArrayList<Object>(); 
List<String> y = new ArrayList<String>(); 
// x = y; Will throw Compilation exception 
List<? extends Object> z = y; //will pass compilation 

Można zaobserwować, że można dodać powiedzieć String zarówno do x, a lista y jednak będzie ona przydatna, gdy piszesz powiedzieć funkcję biblioteki (takie jak printCollection w przykładzie pokazane w łączu), a nie akceptując Collection<Object>, w którym to przypadku użytkownik nie może przekazać swojej listy łańcuchów, które ma do swojej metody, jeśli zaakceptujesz Collection<? extends Object>, wtedy użytkownik może przekazać swoją Collection<Apple>, Collection<Orange> itd. bez konieczności jawnego tworzenia kolejnej listy.

0

X nie można dodać do List<Y>, nawet jeśli X można przekonwertować na Y.

Więc, w drugim przypadku, jeśli List<X> l; pozwolono, aby dodać podklasę X, który złamie Podstawową zasadą bezpieczeństwa typu