1047 Stimmen

Unterschied zwischen <? super T> und <? extends T> in Java

Was ist der Unterschied zwischen List<? super T> y List<? extends T> ?

Ich benutzte früher List<? extends T> aber es erlaubt mir nicht, Elemente hinzuzufügen list.add(e) während die List<? super T> tut.

39 Stimmen

Sehen Sie sich diesen ausgezeichneten Vortrag an: youtu.be/V1vQf4qyMXg?t=22m24s

1 Stimmen

Hier null können wir hinzufügen

0 Stimmen

Eine sehr gute Erklärung mit einem Beispiel @ youtube.com/watch?v=34oiEq9nD0M&feature=youtu.be&t=1630, die den <? super T> Teil erklärt, aber eine Idee von einem anderen gibt.

21voto

Istao Punkte 7245

Super ist eine Untergrenze und extends ist eine Obergrenze.

Nach Angaben von http://download.oracle.com/javase/tutorial/extra/generics/morefun.html :

Die Lösung besteht in der Verwendung einer Form von gebundenen Platzhalters, die wir noch nicht gesehen haben: Wildcards mit einer Untergrenze. Die Syntax ? super T kennzeichnet einen unbekannten Typ, der ein Supertyp von T ist (oder T selbst ist; beachten Sie, dass die supertype Beziehung reflexiv ist). Es ist das Dual der begrenzten Platzhalter, die wir bisher verwendet haben, wo wir ? extends T verwenden, um einen unbekannten Typ bezeichnen, der ein Untertyp von T ist.

14voto

elyor Punkte 948

Hinzufügen eines Eintrags zur Liste:

  • Liste< ? extends X > erlaubt es nicht, etwas hinzuzufügen, außer null in die Liste aufnehmen.

  • Liste< ? super X > erlaubt es, alles hinzuzufügen, was-a X (X oder sein Subtyp) oder null ist.

Abrufen eines Elements aus der Liste:

  • Wenn Sie einen Gegenstand von Liste< ? extends X > können Sie sie einer Variablen vom Typ X oder einem beliebigen Supertyp von X, einschließlich Object, zuweisen.
  • Wenn Sie einen Gegenstand von Liste< ? super X > können Sie sie nur einer Variablen des Typs Object .

Einige Beispiele:

    List<? extends Number> list1 = new ArrayList<Integer>();
    list1.add(null);  //OK
    Number n = list1.get(0);  //OK
    Serializable s = list1.get(0);  //OK
    Object o = list1.get(0);  //OK

    list1.add(2.3);  //ERROR
    list1.add(5);  //ERROR
    list1.add(new Object());  //ERROR
    Integer i = list1.get(0);  //ERROR

    List<? super Number> list2 = new ArrayList<Number>();
    list2.add(null);  //OK
    list2.add(2.3);  //OK
    list2.add(5);  //OK
    Object o = list2.get(0);  //OK

    list2.add(new Object());  //ERROR
    Number n = list2.get(0);  //ERROR
    Serializable s = list2.get(0);  //ERROR
    Integer i = list2.get(0);  //ERROR

6voto

Shailesh Pratapwar Punkte 3851

Die hochgestimmten Antworten decken die Details zu vielen Aspekten ab. Ich würde jedoch versuchen, die Frage auf andere Weise zu beantworten.

Es gibt 2 Dinge, die wir berücksichtigen müssen,

1. Zuweisung an die Listenvariable

List<? extends X> listvar;

Hier wird jede Liste von X oder Liste von Unterklassen von X zugewiesen werden kann zu listvar.

List<? extends Number> listvar; listvar = new ArrayList<Number>(); listvar = new ArrayList<Integer>();


List<? super X> listvar;

Hier wird jede Liste von X oder Liste von Superklassen von X zugewiesen werden kann zu listvar.

List<? super Number> listvar; listvar = new ArrayList<Number>(); listvar = new ArrayList<Object>();

2. Lese- oder Schreiboperation auf der Listenvariablen durchführen

`List<? extends X> listvar;`

Sie können diese Funktion verwenden, um eine Liste von Methodenargumenten zu akzeptieren und beliebige Operationen auf Typ X (Hinweis: Sie können nur Objekte des Typs X lesen aus der Liste).

`List<? super Number> listvar;

Sie können diese Funktion verwenden, um eine Liste von Methodenargumenten zu akzeptieren und beliebige Operationen auf Typ Objekt wie Sie können nur Objekte vom Typ Object lesen aus der Liste. Aber ja, zusätzlich können Sie Objekte des Typs X in die Liste aufnehmen.

5voto

Sai Sunder Punkte 961

使用方法 erweitert können Sie nur aus der Sammlung erhalten. Sie können nicht in die Sammlung aufgenommen werden. Außerdem, obwohl super erlaubt sowohl get als auch put, der Rückgabetyp bei get ist ? super T .

5voto

jforex78 Punkte 315

Sie können alle Antworten oben durchgehen, um zu verstehen, warum die .add() ist beschränkt auf '<?>' , '<? extends>' und teilweise auf '<? super>' .

Aber hier ist die Schlussfolgerung, wenn Sie sich das merken wollen und nicht jedes Mal nach der Antwort suchen wollen:

List<? extends A> bedeutet, dass dies jede List de A und Unterklasse von A . Aber Sie können dieser Liste nichts hinzufügen. Nicht einmal Objekte des Typs A .

List<? super A> bedeutet, dass dies eine beliebige Liste von A und Oberklasse von A . Sie können Objekte des Typs A und seine Unterklassen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X