Was ist der Unterschied zwischen <?> Und <? erweitert Object> in Java Generics?

94

Ich habe gesehen, dass der Wildcard, der zuvor verwendet wurde, ein Objekt bedeutet - aber kürzlich wurde Folgendes verwendet:

<? extends Object>

Sind diese beiden Verwendungen synonym, da alle Objekte Object erweitern?

Orbfish
quelle
2
Das ist gleich. Siehe stackoverflow.com/questions/2274720/…
Dan
3
@Dan Wenn Sie in dieser Frage nach "? Erweitert Objekt" suchen, finden Sie nichts. Ich lese die Antworten durch, um zu sehen, ob ich etwas ableiten kann, aber ich glaube nicht, dass es das ist. Insbesondere geht es nicht um Generika.
Orbfish
@ Dan - Das ist eine andere Frage. Ich habe diese Frage schon einmal gesehen und erinnere mich zumindest an die Erwähnung eines subtilen Unterschieds. Lassen Sie mich sehen, ob ich es finden kann ..
Paul Bellora
Es ist auch nicht dieses, wenn Sie es finden: stackoverflow.com/questions/678822/…
orbfish
1
Los geht's: Mögliches Duplikat von Ungebundenen Platzhaltern in Java (mit einer falschen Antwort von Kevin Bourrillion nicht weniger.)
Paul Bellora

Antworten:

103

<?>und <? extends Object>sind auch, wie man es erwarten würde.

Es gibt einige Fälle mit Generika, in denen dies extends Objectnicht redundant ist. Zum Beispiel <T extends Object & Foo>wird es Tzu einer ObjectLöschung führen, während <T extends Foo>es damit zu einer FooLöschung wird. (Dies kann von Bedeutung sein, wenn Sie versuchen, die Kompatibilität mit einer verwendeten vorgenerischen API beizubehalten Object.)

Quelle: http://download.oracle.com/javase/tutorial/extra/generics/convert.html ; Es erklärt, warum die java.util.CollectionsKlasse des JDK eine Methode mit dieser Signatur hat:

public static <T extends Object & Comparable<? super T>> T max(
    Collection<? extends T> coll
)
Ruakh
quelle
4
Ich bin mir nicht sicher, wie sich das Beispiel bezieht. (da es weder <?> noch <? erweitert Objekt> verwendet)
Orbfish
27
@orbfish: Sie bezieht sich nur dadurch , dass ich dachte , Sie würden es interessant finden, da es ein Beispiel ist , wo extends Objecteigentlich ist sinnvoll. Wenn ich mich geirrt habe, entschuldige ich mich. Hoffentlich ist es zumindest für andere Leute von Interesse, die auf Ihre Frage stoßen.
Ruakh
@ruakh - War eher an begrenzten Platzhaltern als an Typparametern interessiert, aber zumindest haben Sie geantwortet.
Orbfish
1
Das hättest du dann in deinem ursprünglichen Beitrag angeben sollen. Auf diese Weise hätte seine Antwort für Sie relevanter sein können.
Liltitus27
19

Obwohl <?>es eine Abkürzung für sein soll <? extend object>, gibt es einen winzigen Unterschied zwischen den beiden. <?>ist reifizierbar, solange <? extend object>nicht. Der Grund dafür ist, dass es einfacher ist, einen reifizierbaren Typ zu unterscheiden. Alles, was so aussieht <? extends something>, <T>ist <Integer>nicht reif.

Zum Beispiel würde dieser Code funktionieren

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

Dies gibt jedoch einen Fehler

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

Weitere Informationen finden Sie unter Java-Generika und -Sammlungen von Maurice Naftalin

Renzhentaxi Baerde
quelle
Wie kann List <?> Überprüfbar sein, wenn der Compiler es in List <Object> übersetzt, um Informationen über den Typ zu erhalten? ist verloren?
Trismegistos
Was ich glaube, <?> Ist eher für die Abwärtskompatibilität mit Legacy-APIs konzipiert. mit <Objekt> und <zu unterscheiden? erweitert Object>, die Post-Java 5-Code sind.
Dennis C
9

<?>ist eine Abkürzung für <? extends Object>. Sie können den unten angegebenen Link für weitere Details lesen.


<?>

"?"bezeichnet einen unbekannten Typ. Er kann einen beliebigen Typ im Code für darstellen. Verwenden Sie diesen Platzhalter, wenn Sie sich bei Type nicht sicher sind.

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

Hinweis: <?> bedeutet alles. Es kann also vom Typ akzeptiert werden, die nicht von der ObjectKlasse geerbt werden .

<? extends Object>

<? extends Object>bedeutet, dass Sie ein Objekt oder eine Unterklasse übergeben können, die die Klasse erweitert Object.

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

Geben Sie hier die Bildbeschreibung ein

T - bezeichnet den Typ
E - bezeichnet das Element
K - Tasten
V - Werte
N - für Zahlen
Ref:

Geben Sie hier die Bildbeschreibung ein

Roottraveller
quelle
"Es kann also vom Typ akzeptiert werden, die nicht von der Objektklasse geerbt werden", aber alle Java-Klassen werden von der ObjectKlasse geerbt oder implizit geerbt .
Hackjutsu