2013-08-12 4 views
5

Ich lese mehrstufige Wildcards von AngelikaLangerGenericsFaq. Ich bin ziemlich verwirrt über die Syntax. Das Dokument sagtWas sind Multilevel-Wildcards? Verwechslung in der Syntax

Der Typ Collection<Pair<String,?>> eine konkrete Ausprägung der generischen Collection-Schnittstelle ist. Es ist eine heterogene Sammlung von Paaren verschiedener Typen. Es kann Elemente vom Typ Pair<String,Long>, Pair<String,Date>, Pair<String,Object>, Pair<String,String> und so weiter und so weiter enthalten. Mit anderen Worten, Collection<Pair<String,?>> enthält eine Mischung von Paaren verschiedener Typen der Form Pair<String,?>. Der Typ Collection<? extends Pair<String,?>> ist ein Platzhalter parametrisierter Typ. es steht NICHT für einen konkreten parametrierten Typ. Es steht für einen Vertreter aus der Familie der Kollektionen , die Instanzen der Collection-Schnittstelle sind, wobei das Argument das Format Pair<String,?> hat. Kompatible Instanziierungen sind Collection<Pair<String,Long>>, Collection<Pair<String,String>>, Collection<Pair<String,Object>> oder Collection<Pair<String,?>>. In anderen Worten wissen wir nicht, welche Instanziierung der Sammlung es steht für.

Als Faustregel müssen Sie mehrstufige Wildcards von oben nach unten lesen.

Ich bin verwirrt über die folgenden Punkte.

  1. Kann jemand diese drei Zitate mit Beispiel ausarbeiten. Ich bin total in die Syntax verloren
  2. Dokument sagt, Para-1 ist die konkrete Instantiierung eines generischen Typs und andere ist nicht die konkrete Instanziierung? Wie ist das?
  3. Was bedeutet es, die Wild-Cards von oben nach unten zu lesen?
  4. Welchen Vorteil haben Multi-Level-Joker?

Kann jemand diese Punkte ausarbeiten. Vielen Dank.

Antwort

11

Kann jemand diese drei Zitate mit Beispiel näher erläutern. Ich bin total in die Syntax verloren

Nun, es wäre nicht sinnvoll, diese 3 Zitate hier wieder zu schreiben. Wie kann ich keine bessere Erklärung geben als das. Stattdessen werde ich versuchen, Ihre anderen Fragen unten zu beantworten, dann werden Sie möglicherweise auch diesen verstehen. Wenn nicht, können Sie Ihre Anfrage erneut stellen. Ich werde dann versuchen, etwas weiter zu gehen.

Dokument sagt, Para-1 ist die konkrete Instanziierung eines generischen Typs und andere ist nicht die konkrete Instanziierung? Wie ist das?

Eine konkrete Instantiierung ist diejenige, in der alle Typargumente vom konkreten Typ sind und zum Zeitpunkt der Kompilierung bekannt sind. Für z.B.List<String> ist eine konkrete Instanziierung, weil String ein Betontyp ist. Der Typ ist zur Kompilierzeit bekannt. In der Erwägung, List<? extends Number> ist kein konkreter Typ, denn ? extends Number kann jeden Typ, der Number erweitert. Daher ist der Typ zum Zeitpunkt der Kompilierung unbekannt. In ähnlicher Weise ist Map<String, Integer> eine konkrete Instanziierung des generischen Typs Map<K, V>.

Im Fall von Multi-Level-Typ-Parametern, List<List<? extends Number>>, der äußerte List ist eine konkrete Instanziierung List<E>, weil die Art der Elemente bekannt ist ein List zur Kompilierzeit sein, obwohl die inneren List eine Wildcard Instanziierung ist, wie Der Typ der gespeicherten Elemente kann Integer, Double, jede Unterklasse von Number sein. Aber dieser Absatz spricht nur vom äußeren Typ. Und der äußere Typ kann nur den Typ List enthalten.

Deshalb ist der erste Absatz gesagt, es ist ein heterogenes Sammlung von Pair, da der tatsächlichen Typparameter Pair kann alles sein, aber das ist sicher Pair und nichts anderes sein.

Was bedeutet es, die Wild-Cards von oben nach unten zu lesen?

In der Laiensprache gesprochen bedeutet es von links nach rechts. Während Sie den Typ des parametrisierten Typs bestimmen, sehen Sie zunächst den äußersten Typparameter. Wenn dieser Typparameter selbst ein parametrisierter Typ ist, wechseln Sie zu den Typparametern dieses parametrisierten Typs. Also lesen wir die Typparameter von links nach rechts.

Was ist der Vorteil von mehrstufigen Wildcards?

Angenommen, Sie möchten eine Liste der Liste der Früchte erstellen. Jetzt kann Ihre innere List jede Art von Früchten enthalten. Eine Apple ist auch eine Frucht, und eine Banane ist auch eine Frucht. Also, Sie müssen sicherstellen, dass Sie alle bekommen. Jetzt, da generische Typen invariant sind, in dem Sinne, List<Apple> ist nicht dasselbe wie List<Fruit>, können Sie keine List<Apple> hinzufügen, wenn Ihr Listentyp List<List<Fruit>> ist. Dafür müssten Sie wildcards wie folgt verwenden - List<List<? extends Fruit>>, die jetzt List<Apple>, List<Banana>, Liste aller Früchte nehmen kann.

+0

danke rohit für so eine ausführliche Erklärung. Lets siehe Collection >, es enthält eine Platzhalter-Notation dann, wie es konkret sein kann, Compiler wird nicht wissen, was der andere Typ ist. Wie können wir es dann als konkret bezeichnen? – benz

+1

@benz. Ich habe eine Erklärung dazu hinzugefügt. Bitte überprüfen Sie die Bearbeitung. –

+0

Erstaunliche Erklärung Rohit. Vielen Dank. Ich habe noch mehr Zweifel am selben Thema, ich bin am Ende und werde die Frage bearbeiten, weil es ziemlich wichtig ist, sie hier hinzuzufügen. – benz

0

Generische Typen mit Platzhaltern sind wirklich "existenzielle" Typen. Wenn Sie mit der Logik vertraut sind, können Sie G< ? extends T > als ∃ S extends T:G<S> lesen.

Angelas Erklärung zu Lesetypen "von oben nach unten" bedeutet, dass der imaginäre Existenzquantor, der von einem Typ mit einem ? darin enthalten ist, immer so nah wie möglich an dem ? liegt. Zum Beispiel sollten Sie mental G< H< ? extends T > > zu G<S extends T:H<S> > umschreiben. Da es außen keinen Quantor gibt, heißt das Beton.