Qual è la differenza tra <?> E <? estende Object> in Java Generics?


94

Ho visto il carattere jolly usato prima per indicare qualsiasi oggetto, ma recentemente ho visto un uso di:

<? extends Object>

Poiché tutti gli oggetti estendono Object, questi due usi sono sinonimi?


2
È la stessa cosa. Vedi stackoverflow.com/questions/2274720/…
Dan

3
@ Dan Se cerchi "? Extends Object" in quella domanda non trovi nulla. Sto leggendo le risposte per vedere se posso dedurre qualcosa ma non penso che sia questo. Nello specifico, non si tratta di generici.
orbfish

@ Dan - Questa è una domanda diversa. Ho già visto questa domanda e ricordo almeno una menzione di una sottile differenza. Fammi vedere se riesco a trovarlo ..
Paul Bellora

Non è anche questo uno se lo trovate: stackoverflow.com/questions/678822/...
orbfish

1
Eccoci: possibile duplicato di caratteri jolly illimitati in Java (con una risposta non corretta di Kevin Bourrillion non meno.)
Paul Bellora

Risposte:


103

<?>e <? extends Object>sono anche, come ti aspetteresti.

Ci sono alcuni casi con generici in cui extends Objectnon è effettivamente ridondante. Ad esempio, <T extends Object & Foo>causerà Ta diventare Objectsotto cancellatura, mentre con <T extends Foo>diventerà Foosotto cancellatura. (Questo può essere importante se stai cercando di mantenere la compatibilità con un'API pre-generica utilizzata Object.)

Fonte: http://download.oracle.com/javase/tutorial/extra/generics/convert.html ; spiega perché la java.util.Collectionsclasse JDK ha un metodo con questa firma:

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

4
Non sono chiaro come si relaziona l'esempio? (poiché non usa né <?> né <? extends Object>)
orbfish

27
@orbfish: si riferisce solo al fatto che pensavo lo avresti trovato interessante, in quanto è un esempio in cui in extends Objectrealtà è significativo. Se mi sono sbagliato, mi scuso. Spero che possa interessare almeno altre persone che incontrano la tua domanda.
ruakh

@ruakh - Era interessato ai caratteri jolly limitati piuttosto che ai parametri di tipo, ma, almeno, hai risposto.
orbfish

1
Avresti dovuto affermarlo nel tuo post originale allora. In questo modo, la sua risposta avrebbe potuto essere più pertinente per te.
liltitus27

19

Anche se <?>dovrebbe essere una scorciatoia <? extend object>, c'è una piccola differenza tra i due. <?>è reificabile mentre <? extend object>non lo è. Il motivo per cui lo hanno fatto è per rendere più facile distinguere il tipo riconfigurabile. Tutto ciò che sembra <? extends something>, <T>, <Integer>sono nonreifiable.

Ad esempio, questo codice funzionerebbe

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

ma questo dà un errore

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

per maggiori informazioni leggi i generici e le raccolte Java di Maurice Naftalin


Come può List <?> Essere modificabile se il compilatore lo traduce in List <Object> quindi le informazioni su di che tipo è? è perduto?
Trismegistos

Quello che credo <?> È più progettato per essere retrocompatibile con le API legacy. distinguere con <Object> e <? estende Object> che sono codice post Java 5.
Dennis C

9

<?>è una scorciatoia per <? extends Object>. Puoi leggere sotto il link condiviso per maggiori dettagli.


<?>

"?"denota qualsiasi tipo sconosciuto, può rappresentare qualsiasi tipo nel codice per. Utilizza questo carattere jolly se non sei sicuro del tipo.

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

Nota: <?> significa qualsiasi cosa. Quindi può accettare tipi che non sono ereditati dalla Objectclasse.

<? extends Object>

<? extends Object>significa che puoi passare un oggetto o una sottoclasse che estende la Objectclasse.

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

inserisci qui la descrizione dell'immagine

T - utilizzato per indicare il tipo
E - utilizzato per indicare l'elemento
K - chiavi
V - valori
N - per i numeri
Rif:

inserisci qui la descrizione dell'immagine


"Quindi può accettare tipi che non sono ereditati dalla classe Object", ma tutte le classi Java sono ereditate o implicitamente ereditate dalla Objectclasse.
hackjutsu
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.