2011-11-08 17 views
67

Widziałem wieloznaczny używana przed oznaczać dowolny obiekt - ale ostatnio widziałem użycia:Jaka jest różnica między <?> a <? rozszerza Object> w Java Generics?

<? extends Object> 

Ponieważ wszystkie obiekty rozciągają się obiekt, są te dwa zwyczaje synonimem?

+2

To to samo. Zobacz http://stackoverflow.com/questions/2274720/java-extends-object-question – Dan

+3

@Dan Jeśli przeszukasz "? Extends Object" w tym pytaniu, nic nie znajdziesz. Czytam odpowiedzi, żeby zobaczyć, czy mogę coś wywnioskować, ale nie sądzę, że to jest to. W szczególności nie chodzi tu o generyczne leki. – orbfish

+0

@Dan - To inne pytanie. Widziałem to już wcześniej i pamiętam przynajmniej wzmiankę o subtelnej różnicy. Pozwól mi zobaczyć, czy mogę go znaleźć .. –

Odpowiedz

77

<?> i <? extends Object> są synonimami, jak można się spodziewać, ale jest kilka przypadków z rodzajami, w których extends Object nie jest w rzeczywistości zbyteczny. Na przykład <T extends Object & Foo> spowoduje, że T stanie się pod ciągłą erozją pod Object, podczas gdy z <T extends Foo> stanie się pod wymyciem wartością Foo. (Może to znaczenia, jeśli starasz się zachować zgodność z API sprzed leków generycznych, które kiedyś Object.)

(Źródło: http://download.oracle.com/javase/tutorial/extra/generics/convert.html; wyjaśnia dlaczego java.util.Collections klasa JDK zawiera metodę z tym podpisem:

public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) 

.)

+4

Nie mam pojęcia, jak ten przykład się odnosi? (ponieważ nie używa ani ani ) – orbfish

+5

+1 Bardzo interesujące niezależnie. –

+22

@orbfish: To odnosi się tylko do tego, że uznałem to za interesujące, ponieważ jest to przykład, w którym 'extends Object' actually * is * meaningful. Jeśli się pomyliłem, przepraszam. Mam nadzieję, że spotka się to z zainteresowaniem innych osób, które natrafią na twoje pytanie. – ruakh

17

Chociaż <?> ma być skrótem dla <? extend object>, istnieje niewielka różnica między tymi dwoma. <?> jest możliwe do przeliczenia, gdy <? extend object> nie jest. Powodem, dla którego to zrobili, jest ułatwienie rozróżnienia typów realnych. Wszystko, co wygląda jak <? extends something>, , <Integer>, jest nierefundowalne.

Na przykład ten kod będzie działać

List aList = new ArrayList<>(); 
boolean instanceTest = aList instanceof List<?>; 

ale to daje błąd

List aList = new ArrayList<>(); 
boolean instancetest = aList instanceof List<? extends Object>; 

uzyskać więcej informacji czytaj rodzajowych Java i zbiory Maurice Naftalin

+0

Jak można wymienić listę , jeśli kompilator przetłumaczy ją na listę , aby uzyskać informacje o tym, jaki jest typ? zgubiony? – Trismegistos

+0

Co uważam, że jest bardziej zaprojektowany pod kątem zgodności wstecznej ze starszymi interfejsami API. w celu odróżnienia od i , które są po kodzie Java 5. –

2

<?> jest skrótem <? extends Object>. Możesz przeczytać poniżej link udostępniony, aby uzyskać więcej informacji.


<?> 

"?" oznacza dowolny nieznanego typu, może reprezentować dowolny typ co w kodzie dla. Użyj tego symbolu wieloznacznego, jeśli nie masz pewności co do typu.

ArrayList<?> unknownList = new ArrayList<Number>(); //can accept of type Number 
unknownList = new ArrayList<Float>(); //Float is of type Number 

Uwaga:<?> oznacza anythings. Więc może zaakceptować typ, który nie jest dziedziczony z klasy Object.

<? extends Object> 

<? extends Object> oznacza, że ​​można przekazać obiekt lub podklasę, która rozciąga Object klasę.

ArrayList<? extends Number> numberList = new ArrayList<Number>(); //Number of subclass 
numberList = new ArrayList<Integer>(); //Integer extends Number 
numberList = new ArrayList<Float>(); // Float extends Number 

enter image description here

t - stosuje się do określenia typu
E - służy do określenia elementowi
k - klucze
V - Wartości
N - numery
Ref:

enter image description here

Powiązane problemy