2016-07-08 23 views
5

Ich stieß auf ein seltsames Problem in meinem Projekt. Nun habe ich das Problem vereinfacht und geschrieben hier ein kleines Beispiel meine Verwirrung zu veranschaulichen:Was ist falsch mit dem Schlüsselwort "super" in Java generischen Typ

public class Question { 
    class Q1 {} 

    class Q2 extends Q1 {} 

    interface In<T> { 
     void f(T t); 
    } 

    List<Q2> list; 

    void f(In<? super List<? super Q2>> in) { 
     in.f(list); 
    } 

    static void g() { 
     Question question = new Question(); 
     In<Collection<Q1>> in1 = new In<Collection<Q1>>() { 
      @Override 
      public void f(Collection<Q1> o) {} 
     }; 
     In<List<Q2>> in2 = new In<List<Q2>>() { 
      @Override 
      public void f(List<Q2> o) {} 
     }; 
     question.f(in1); //Error! 
     question.f(in2); //Error! 
    } 
} 

Mein Ziel ist die Methode f(In<? super List<? super Q2>>) flexibler zu machen. Ich kann in1 oder in2 an die Methode übergeben. Aber beides kann nicht bestanden werden! Was ist falsch?

Vielleicht this answer wird Sinn machen. Aber meine Frage ist anders !!! Mein generischer Typ ist In<? super List<? super Q2>>, ein generischer Typ innerhalb eines generischen Typs.

+0

@AndyTurner "alles passt? Super Q2" also warum 'question.f (in1)' ist ein Fehler? Kannst du mehr klären? – Jerry06

+0

@ Jerry06 Ich glaube, ich habe die Frage falsch interpretiert. Wieder geöffnet. –

Antwort

0
In<Collection<? extends Q1>> in1 = new In<Collection<? extends Q1>>() { 
      @Override 
      public void f(Collection<? extends Q1> o) {} 
     }; 
     In<List<? extends Q2>> in2 = new In<List<? extends Q2>>() { 
      @Override 
      public void f(List<? extends Q2> o) {} 
     }; 
+0

'extend' ist anders. Es ist einfacher. Bitte ändere es in "super" und schau was passiert. –

+0

ja. Gleicher Fehler mit Super – Gangadhar

2

ein generischer Typ des Formulars A<? extends B> bedeutet, dass die ? kann durch B oder jede Art von Super B ersetzt werden. Somit bedeutet List<? super Q2> etwas wie: entweder List<Object>, List<Q1> oder List<Q2>.

Obwohl Q1 ist ein Super-Typ Q2, List<Q1> kein Super-Typ List<Q2> ist. Dies bedeutet, dass der einzige gemeinsame Super-Typ List<Object>, List<Q1> und List<Q2>Object ist. Das einzige, was Sie an Ihre f Methode weitergeben können, ist ein In<Object>.

Wie Sie dies lösen müssen, hängt davon ab, welche Flexibilität Sie tatsächlich benötigen: Welche Art von Objekten möchten Sie an f weitergeben und was wollen Sie mit diesen Objekten tun?

+0

Was ist mit '> '? Und was soll ich tun, wenn ich irgendeine Unterklasse von 'Collection' zu' f' übergeben möchte? –