Erste Schritte <? super Unterklasse> Return-Typ darf nicht vom Wildcard-Typ sein

enero99

Mitglied
Hallo,
habe gelesen, dass bei <? super ...> der Aufruf von Methoden unmöglich ist, deren Return-Typ vom dem Typ ist, für den das Wildcard steht!

Bei der Methode m1()ist doch der Return-Typ gleich dem Wildcard-Typ?
Habe ich etwas falsch verstanden? Für jede Erklärung dankbar.

Gruß und Dank im Voraus
enero99

Java:
import java.util.ArrayList;
import java.util.List;

public class Gen8 {
   public static void main(String[] args) {
     List<C2> l = new ArrayList<C2>();
     l.add(new C2(4711));
     C2 c = new C2(4712);
     m1(l,c);
   }

   @SuppressWarnings("unchecked")
   static <T extends C1> List<T> m1(List<? super T> list, T t) {
     list.add(t);
     return (List<T>) list;
   }
}

class C1 {
   private int v;
   public C1(int v) {super();this.v = v;}
   int getV() {return v;}
   void setV(int v) {this.v = v;}
   }

class C2 extends C1{
   public C2(int v) {super(v);}};
       
class C3 extends C2{
   public C3(int v) {super(v);}};
 
Kannst du bitte die Frage nochmal verständlich forumlieren und eventuell die Textpassage posten, was dort gemeint wurde?

Dein Codesnippet ergibt so keinen Sinn.
 
Irgendwie unnötig, eine Liste und ein Element einer Methode mitzugeben, die einfach nur das Element in die Liste einfügt und die Liste wieder zurückgibt. Da kann man doch gleich das Element selbst in die Liste einfügen. Verstehe den Sinn nicht wirklich.
 
Hallo,
vielen Dank für die vielen Antworten. Der gepostete Code ist nur ein Beispiel um meine Frage zu verdeutlichen bzw. das mir unverständliche Verhalten aufzuzeigen.

Die Information habe ich aus:
http://www.angelikalanger.com/Articles/JavaMagazin/Generics/GenericsPart1.html
(und dort under 1.5 ziemlich am Ende des Absatzes)
...
Der Zugriff auf ein Objekt, das über eine Referenzvariable vom Typ Wildcard-Instanziierung referenziert wird, ist eingeschränkt. Über eine Variable vom Typ List<? extends Number> beispielsweise dürfen keine Methoden des Typs List aufgerufen werden, die ein Argument vom dem Typ nehmen, für den das Wildcard steht. Hier ist ein Beispiel:

List<? extends Number> list = new LinkedList<Integer>();
list.add(new Integer(25)); // compile-time error

Bei einem Wildcard mit "super" ist der Aufruf von Methoden unmöglich, deren Returntyp vom dem Typ ist, für den das Wildcard steht. Für das "?" Wildcard gelten beide Einschränkungen.

Java:
...
   @SuppressWarnings("unchecked")
   static <T extends C1> List<T> m1(List<? super T> list, T t) {
     list.add(t);
     // hier ist doch der Return-Typ gleich dem Typ für den das Wildcard seht!
     return (List<T>) list; // <<<< das dürfte doch nicht gehen oder?
   }
...
 
Hier hast du eine Liste, die Objekte vom Typ T (oder davon abgeleitete Objekte) aufnehmen kann. Da kannst du natürlich Problemlos ein Objekt vom Typ T hinzufügen.
Welchen Typ T annimmt, ist zwar erst zur Laufzeit bekannt, aber zur Compile-Zeit ist bereits bekannt, dass du (für die Dauer von einem Methoden-Durchlauf) überall den gleichen Typ T vorliegen hast. Da gibt es keine Probleme.

In deinem anderen Beispiel ist über list-Variable zur Compile-Zeit nur bekannt, dass sie einen Typ, der von Number ableitet, aufnehmen kann. Du weist anschließend zwar explizit eine "Integer-Liste" zu, aber du könntest zwischenzeitlich der Variable list ja auch z.B. eine "BigDecimal"-Liste o.Ä. zuweisen, der du dann natürlich keine Integer-Variable mehr zuweisen kannst.

Der Integer-Liste kannst du also einen Integer hinzufügen, nicht aber der "Irgendwas, was Number erweitert"-Liste. Folgendes würde zum Beispiel gehen:
Java:
List<? extends Number> list = new LinkedList<Integer>() {{
  add(new Integer(25));
  }};

Genauso wie das:
Java:
List<Number> list = new LinkedList<>();
  list.add(new Integer(25));

Im Grunde ist das eigentlich schon das gleiche Problem, welches hier auftaucht:
Das hier geht:
Java:
List<? extends Number> list = new LinkedList<Integer>();
Aber das hier ist verboten:
Java:
List<Number> list = new LinkedList<Integer>();
 

Zurück
Oben