2009-05-27 16 views
36

Ich habe eine Java-Frage zu Generika. Ich erklärte eine generische Liste:Liste <? erweitert MyType>

List<? extends MyType> listOfMyType; 

Dann in irgendeiner Methode, die ich instanziiert versuchen und fügen Sie Artikel zu dieser Liste:

listOfMyType = new ArrayList<MyType>(); 
listOfMyType.add(myTypeInstance); 

Wo myTypeInstance nur ein Objekt vom Typ ist MyType; Es wird nicht kompiliert. Dort heißt es:

Die Methode add in der Liste Typ < Capture # 3-of (? Capture # 3-of MyType erstreckt)? erstreckt MyType> Jede Idee

ist? nicht anwendbar für die Argumente (MyType)

Antwort

29

Sie können nicht eine "Put" mit erweitert werden. Schauen Sie sich Generics - Get and Put rule an.

+9

Als Josh Bloch sagt: "PECS Denken Sie daran: Der Produzent Verlängert, Consumer ist super." Da listOfMyType ein Consumer ist (Sie fügen ihn hinzu), ist "super" gültig und "extends" nicht. –

+0

Links sind jetzt gebrochen. –

+0

Punkt der Pedanterie: Sie können mit "extends" "null" setzen ".Außerdem können Sie den Typ erfassen und "Referenzen" hinzufügen, die Sie zuvor "bekommen" haben. –

4

Sie sollten nicht die Wildcard-Capture-Syntax in Ihrem Fall verwenden müssen, einfach

erklärt
List<MyType> listOfMytype; 

sollte genügen. Wenn Sie genau wissen wollen, warum, hat die Java Generics Tutorial mehr als Sie jemals über die esoterische Verrücktheit von Java Generics wissen wollen. Seite 20 adressiert Ihren speziellen Fall.

Warum add mit der Platzhalter-Capture nicht funktioniert, liegt daran, dass der Compiler nicht genau bestimmen kann, welche Unterklasse von MyType die Liste in jedem Fall ist, so dass der Compiler einen Fehler ausgibt.

22

Bedenken Sie:

class MySubType extends MyType { 
} 

List<MySubType> subtypeList = new ArrayList<MySubType>(); 
List<? extends MyType> list = subtypeList; 
list.add(new MyType()); 
MySubType sub = subtypeList.get(0); 

sub jetzt eine MyType enthält, die sehr falsch ist.

+0

Sollte nicht die "list.get (0);" eigentlich "subtypeList.get (0);" ? – Zds

+0

@Zds Yup, korrigiert. Vielen Dank. –

2

Es gibt einen ähnlichen Thread hier: How can elements be added to a wildcard generic collection?

Um eine Vorstellung davon zu bekommen, wie Generika Werke dieses Beispiel finden Sie unter:

List<SubFoo> sfoo = new ArrayList<SubFoo>(); 
    List<Foo> foo; 
    List<? extends Foo> tmp; 

    tmp = sfoo; 
    foo = (List<Foo>) tmp; 

Die Sache ist, dass nicht für lokale/Mitglied entworfen wurde, Variablen, aber für Funktionssignaturen, deshalb ist es so ass-rückwärts.

2

Ich weiß nicht, ob dies wirklich helfen, aber das ist etwas, das ich benutzen musste, während ein generisches Verfahren zum Spring Framework aufrufen und auch eine generische Liste zurückkehren wollen:

public <T> List<T> findAll(String tableName,Class<?> table) { 
    String sql = "SELECT * FROM "+ tableName ; 
    List<?> entities = getSimpleJdbcTemplate().query(sql, 
      ParameterizedBeanPropertyRowMapper.newInstance(table)); 
      return (List<T>) entities; 
} 

scheint die Parametrisierung Bedürfnisse Sie benutzen die? Melden Sie sich in der Liste an, um die Ergebnisse zu erhalten, und wandeln Sie die Liste anschließend in den erwarteten Rückgabetyp um.

Iam noch durch Generika geblendet ...

Verwandte Themen