Ich habe das O'Reilly-Buch gelesen, indem ich dieses Get-Put-Prinzip kennengelernt habe .
- Verwenden Sie einen
extends
Platzhalter , wenn Sie nur bekommen Werte aus einer Struktur.- Verwenden Sie einen
super
Platzhalter , wenn Sie nur setzen Werte in eine Struktur.- Verwenden Sie keinen Platzhalter, wenn Sie beide von / zu einer Struktur abrufen und dort ablegen möchten.
Ausnahmen sind:
Sie können nichts in einen mit einem
extends
Platzhalter deklarierten Typ einfügen, außer den Wertnull
, der zu jedem Referenztyp gehört.Sie können aus einem mit einem
super
Platzhalter deklarierten Typ nichts herausholen, außer einem Wert vom TypObject
, der ein Supertyp für jeden Referenztyp ist.
Kann mir jemand helfen, diese Regel eingehend zu untersuchen? Wenn möglich, setzen Sie sie bitte hierarchisch.
Antworten:
Betrachten Sie ein paar Bananen. Dies ist
Collection<? extends Fruit>
insofern eine Sammlung einer bestimmten Obstsorte - aber Sie wissen (aus dieser Erklärung) nicht, um welche Obstsorte es sich handelt. Sie können erhalten Sie ein Element aus und es weiß , es wird auf jeden Fall eine Frucht sein, aber Sie können nicht hinzufügen , um es - Sie könnten versuchen , einen Apfel zu einem Bündel Bananen hinzuzufügen, die auf jeden Fall falsch wäre. Sie können es ergänzennull
, da dies ein gültiger Wert für jede Art von Obst ist.Betrachten Sie nun eine Obstschale. Dies ist
Collection<? super Banana>
insofern eine Sammlung eines Typs, der "größer als" istBanana
(zum BeispielCollection<Fruit>
oderCollection<TropicalFruit>
). Sie können definitiv eine Banane hinzufügen, aber wenn Sie einen Gegenstand aus der Schüssel holen, wissen Sie nicht, was Sie bekommen - es kann durchaus keine Banane sein. Alles, was Sie sicher wissen, ist, dass es sich um eine gültige (möglicherweisenull
)Object
Referenz handelt.(Im Allgemeinen ist die Java Generics-FAQ für Fragen zu Java-Generika eine hervorragende Ressource, die die Antwort auf fast alles enthält, was mit Generika zu tun hat.)
quelle
Collection<? extends Fruit>
genau diesem Grund etwas anderes als null zu a hinzufügen , und Sie müssen das Ergebnis des Abrufs eines Elements aus genau diesen Gründen explizit umwandeln.Collection<? extends Person>
(oder wahrscheinlicher nur einenIterable<? extends Person>
, aber ...). Der Code , der diese Sammlung erstellt, muss möglicherweise ein Code seinCollection<Employee>
, der konsumierende Code jedoch nicht.