2009-05-04 2 views
2

Ich habe die folgenden Klassen:Warum ist es nicht möglich, eine generische Füllmethode in Java zu erstellen?

abstract class DTO{ } 

class SubscriptionDTO extends DTO { } 

und die folgende generische Methode:

protected void fillList(ResultSet rs, ArrayList<? extends DTO> l) 
     throws BusinessLayerException { 
    SubscriptionDTO bs; 
    try { 
     while (rs.next()){ 
      //initialize bs object... 
      l.add(bs); //compiler error here 
     } 
    } catch (SQLException e) { 
     e.printStackTrace(); 
    } 

} 

ich nicht zu verstehen scheinen kann, warum Sie nicht eine generische Methode zum Füllen von DTO-Subtypen schaffen. Mache ich etwas falsch oder ist das Absicht? Wenn ja, gibt es einen Workaround? Danke im Voraus.

+0

zu beantworten, müsste ich, um zu sehen, wie Sie bs initialisieren, zumindest die Typdeklaration. – Yishai

+0

Ich denke nicht, dass Sie die generische Methode wie geplant schreiben können, da Sie den genauen Typ des bs-Objekts kennen müssen, um es zu erstellen. Zum Beispiel neue SubscriptionDTO() oder neue DeliveryDTO(). – javashlook

+0

@javashlook -Sie haben Recht. mmyers Erklärung ist gut genug für mich, das zu erkennen. Es scheint, dass ich eine rohe Lösung für diese Art von Problemen verwenden werde. –

Antwort

7

Sie sollten <? super DTO> (oder <? super SubscriptionDTO>, wie Tom Hawtin - tackline weist darauf hin) als der generische Parameter der ArrayList.

Ab Position 28 von Effective Java (Seite 28 der sample chapter [pdf]):

ist hier ein mnemonic, um Ihnen das Wildcard-Typ erinnern zu verwenden:

PECS steht für Erzeuger- erweitert, Verbraucher-Super.

Mit anderen Worten, wenn ein parametrisierter Typ einen T Producer darstellt, verwenden Sie <? extends T>; Wenn es einen T Verbraucher darstellt, verwenden Sie <? super T>.

In diesem Fall l ein Verbraucher (Sie Objekte es sind vorbei), so dass die <? super T> Typ geeignet ist.

+1

Oder . –

2

Stellen Sie sich folgende Situation, mit Foo extends Bar und Zoo extends Bar

List<Foo> fooList = new ArrayList<Foo>(); 
fooList.addAll(aBunchOfFoos()); 
aMethodForBarLists(fooList); 

dann haben wir die Methode selbst:

void aMethodForBarLists (List<? extends Bar> barList) { 
    barList.add(new Zoo()); 
} 

Was hier passiert, ist, dass, obwohl Zoo Bar erstreckt, Sie‘ Versuchen Sie, einen Zoo in einem List<Foo> hinzuzufügen, der explizit für und nur für Foos gemacht wird.

Diese ist, warum die Java-Spezifikation Zeug nicht zulässt Zugabe in eine <? extends Something> Collection - es kann nicht sicher sein, dass, während die Syntax richtig erscheint, erlauben würde, die tatsächlichen Objekte Sachen in die Sammlung hinzufügen.

2

Dies sollte funktionieren, und ist einfacher:

protected void fillList(ResultSet rs, List<DTO> l) throws BusinessLayerException 
{ 
    SubscriptionDTO bs; 
    try 
    { 
     while (rs.next()) 
     { 
     //initialize bs object... 
     l.add(bs); 
     } 
    } 
    catch (SQLException e) 
    { 
     e.printStackTrace(); 
    } 

}

Verwandte Themen