Unterschied zwischen "*" und "Any" in Kotlin-Generika

106

Ich bin nicht sicher, ob ich den Unterschied zwischen SomeGeneric<*>und vollständig verstehe SomeGeneric<Any>. Ich denke, *repräsentiert alles (Platzhalter) und Anyrepräsentiert das Objekt, von dem ALLE Objekte erben. Es scheint also, dass sie gleich sein sollten, aber sind sie es?

Radbauer
quelle

Antworten:

158

Es kann hilfreich sein, sich die Sternprojektion als eine Möglichkeit vorzustellen, nicht nur irgendeinen Typ darzustellen, sondern einen festen Typ, von dem Sie nicht genau wissen, was er ist.

Zum Beispiel MutableList<*>repräsentiert der Typ die Liste von etwas (Sie wissen nicht genau, was). Wenn Sie also versuchen, dieser Liste etwas hinzuzufügen, werden Sie keinen Erfolg haben. Es kann eine Liste von Strings oder eine Liste von Ints oder eine Liste von etwas anderem sein. Der Compiler erlaubt es überhaupt nicht, Objekte in diese Liste aufzunehmen, da er nicht überprüfen kann, ob die Liste Objekte dieses Typs akzeptiert. Wenn Sie jedoch versuchen, ein Element aus einer solchen Liste herauszuholen, erhalten Sie mit Sicherheit ein Objekt vom Typ Any?, da alle Objekte in Kotlin von erben Any.

Aus dem folgenden Kommentar von asco :

Darüber hinaus List<*>können Objekte eines beliebigen Typs, jedoch nur dieser Typ, enthalten sein, sodass Zeichenfolgen (aber nur Zeichenfolgen) List<Any> enthalten sein können , während Zeichenfolgen und Ganzzahlen und so weiter in derselben Liste enthalten sein können.

Alexander Udalov
quelle
83
Gute Antwort, für einige kann es hilfreich sein, hinzuzufügen, dass List <*> Objekte eines beliebigen Typs enthalten kann , aber nur diesen Typ, sodass Strings (aber nur Strings) enthalten können, während List <Any> Strings und Integers und enthalten kann was auch immer, alle in der gleichen Liste.
Fweigl
1
Hier ein interessanter Artikel mit einer ähnlichen Erklärung: typealias.com/guides/star-projections-and-how-they-work
Kroko
28

In dem Kontext denke ich, dass Sie implizieren, SomeGeneric<*>ist gleichbedeutend mit SomeGeneric<out Any?>. Das Java-Äquivalent ist SomeGeneric<? extends Object>.

Die Syntax heißt "Sternprojektionen". Hier sind die offiziellen Dokumente: https://kotlinlang.org/docs/reference/generics.html#star-projections

Voddan
quelle