Dies ist ein kleiner Codeausschnitt aus einigen Beispielen, die dem Stanford Parser beiliegen. Ich habe in Java seit ungefähr 4 Jahren entwickelt, aber nie ein sehr starkes Verständnis dafür gehabt, was dieser Codestil anzeigen soll.
List<? extends HasWord> wordList = toke.tokenize();
Ich mache mir keine Sorgen um die Details des Codes. Was mich verwirrt, ist, was genau der generische Ausdruck auf Englisch vermitteln soll.
Kann mir das jemand erklären?
Antworten:
bedeutet "Eine Klasse / Schnittstelle, die sich erweitert
HasWord
." Mit anderen Worten, sichHasWord
selbst oder eines seiner Kinder ... im Grunde alles, was mitinstanceof HasWord
Plus funktionieren würdenull
.In technischer Hinsicht
? extends HasWord
handelt es sich um einen begrenzten Platzhalter, der in Punkt 31 der 3. Ausgabe von Effective Java ab Seite 139 behandelt wird. Dasselbe Kapitel aus der 2. Ausgabe ist online als PDF verfügbar . Der Teil auf begrenzten Platzhaltern ist Punkt 28 ab Seite 134.Update: Der PDF-Link wurde aktualisiert, da Oracle ihn vor einiger Zeit entfernt hat. Es verweist nun auf die Kopie, die von der School of Electronic Engineering and Computer Science der Queen Mary University in London gehostet wird.
Update 2: Gehen wir etwas genauer darauf ein, warum Sie Platzhalter verwenden möchten.
Wenn Sie eine Methode deklarieren, deren Signatur erwartet, dass Sie übergeben
List<HasWord>
, können Sie nur a übergebenList<HasWord>
.Wenn diese Signatur jedoch vorhanden
List<? extends HasWord>
ist, können SieList<ChildOfHasWord>
stattdessen eine übergeben.Beachten Sie, dass es einen subtilen Unterschied zwischen
List<? extends HasWord>
und gibtList<? super HasWord>
. Wie Joshua Bloch es ausdrückte: PECS = Produzent-erweitert, Konsumenten-Super.Dies bedeutet, dass Sie verwenden sollten, wenn Sie eine Sammlung übergeben, aus der Ihre Methode Daten abruft (dh die Sammlung produziert Elemente für Ihre Methode)
extends
. Wenn Sie eine Sammlung übergeben, zu der Ihre Methode Daten hinzufügt (dh die Sammlung verbraucht Elemente, die Ihre Methode erstellt), sollte sie verwendet werdensuper
.Das mag verwirrend klingen. Allerdings können Sie es sehen
List
‚s -sort
Befehl (die nur eine Verknüpfung zu den beiden argument Version von Collections.sort ist). Anstatt a zu nehmenComparator<T>
, braucht es tatsächlich aComparator<? super T>
. In diesem Fall verbraucht der Komparator die Elemente vonList
, um die Liste selbst neu zu ordnen.quelle
List<HasWord>
ist genau das, was Sie beschreiben: Eine Liste, die alle Objekte enthält,x
für diex instanceof HasWord
true zurückgegeben wird, undnull
. Sie benötigen dafür keinen Platzhalter. Der Platzhalter bedeutet, dass es sich tatsächlich auch um eine Liste eines anderen Typs handeln kann, sofern dieser Typ ein Subtyp von istHasWord
. (Entschuldigung für den späten Kommentar.)Ein Fragezeichen ist ein Bezeichner für "jeden Typ".
?
allein bedeutetwährend Ihr Beispiel oben bedeutet
quelle
public Set<Class<?>> getClasses()
das? Was ist der Unterschied zuSet<Class>
? Ich schauejavax.ws.rs.core.Application
.List<? extends HasWord>
akzeptiert alle konkreten Klassen, die HasWord erweitern. Wenn Sie die folgenden Klassen haben ...... die
wordList
Dose NUR eine Liste von entweder As oder Bs oder eine Mischung aus beiden enthalten kann, da beide Klassen dasselbe übergeordnete Element erweitern odernull
(was die Instanz von Prüfungen nicht bestehtHasWorld
).quelle
List<? extends Collection<String>> list = new ArrayList<List<String>>();
.List<HasWord>
keine Platzhalter: tut das auch. Der Punkt hier ist, dass diese Variable einList<A>
oderList<B>
sowie ein enthalten kannList<HasWord>
.Vielleicht würde ein erfundenes Beispiel aus der "realen Welt" helfen.
An meinem Arbeitsplatz haben wir Mülleimer, die in verschiedenen Geschmacksrichtungen erhältlich sind. Alle Mülleimer enthalten Müll, aber einige Mülleimer sind Spezialisten und nehmen nicht alle Arten von Müll auf. Also haben wir
Bin<CupRubbish>
undBin<RecylcableRubbish>
. Das Typsystem muss sicherstellen, dass ich meine nichtHalfEatenSandwichRubbish
in einen dieser Typen einordnen kann, aber es kann in einen allgemeinen Mülleimer gelangenBin<Rubbish>
. Wenn ich über einen reden wollteBin
vonRubbish
der spezialisiert werden kann , damit ich nicht in unvereinbar Müll setzen, dann das wäreBin<? extends Rubbish>
.(Hinweis:
? extends
bedeutet nicht schreibgeschützt. Zum Beispiel kann ich mit den richtigen Vorsichtsmaßnahmen ein Stück Müll aus einem Behälter unbekannter Spezialität herausnehmen und später an einem anderen Ort zurückstellen.)Ich bin mir nicht sicher, wie viel das hilft. Zeiger zu Zeiger bei Vorhandensein von Polymorphismus ist nicht ganz offensichtlich.
quelle
Auf Englisch:
Im Allgemeinen bedeutet das
?
in Generika jede Klasse. Und dasextends SomeClass
gibt an, dass dieses Objekt erweitert werden mussSomeClass
(oder diese Klasse sein muss).quelle
Das Fragezeichen wird verwendet, um Platzhalter zu definieren . Überprüfen Sie die Oracle-Dokumentation dazu: http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html
quelle