2017-09-07 2 views
1

Ich habe die folgende Klasse:Java Generics und Basisklasse

public abstract class BaseDaoImpl<T extends BaseEntity> implements BaseDao<T> { 


    @Override 
    public T createOrUpdate(T t, User user) { 
     return createOrUpdate(t, true, user); 
    } 

    @Override 
    public void addOnwerUserToEntity(String entityType, Long entityId, User user) { 

     BaseEntity baseEntity = findBaseEntityById(entityType, entityId); 

     baseEntity.addOwnerUser(user); 

     createOrUpdate(baseEntity, user); // compilation error 
    } 

} 

jetzt habe ich folgendes Kompilierungsfehler:

The method createOrUpdate(T, User) in the type BaseDaoImpl<T> is not applicable for the arguments (BaseEntity, User)  

Was mache ich falsch, warum createOrUpdate Verfahren nicht akzeptiert BaseEntity Objekt und wie es zu beheben?

+5

Warum sollte ein "BaseEntity" -Wert akzeptiert werden? Sie haben mit 'createOrUpdate' ein' T' akzeptiert. –

+2

Es ist oft einfacher zu verstehen, wenn Sie die Klassen durch konkrete Beispiele ersetzen. T = Banane. BaseEntity = Frucht. Sie definieren eine Methode createOrUpdate (Banana) und rufen sie mit einem Argument vom Typ Fruit auf. Eine Frucht ist nicht unbedingt eine Banane. Der Compiler akzeptiert den Methodenaufruf also nicht. –

+0

Aber T wird akzeptiert, BaseEntity und Unterklassen zu akzeptieren. Im Moment verstehe ich nicht, warum BaseEntity nicht akzeptiert wird. – alexanoid

Antwort

2

Die Sache ist, T ist nicht unbedingt ein BaseEntity. Sie könnten Klasse instanziiert BaseDaoImpl wie so:

class Widget extends BaseEntity {...} 
BaseDaoImpl<Widget> base = new BaseDaoImpl<>(); 

In diesem Fall T ist ein Widget, und so das Verfahren createOrUpdate(...) wird:

public Widget createOrUpdate(Widget t, User user) { 

und Sie können das nicht nennen mit nur einem BaseEntity.

+0

Übrigens könnten Sie createOrUpdate ändern, um eine BaseEntity zu akzeptieren und zurückzugeben. – Jamie

1

ändern

BaseEntity baseEntity = findBaseEntityById(entityType, entityId); 

zu

T baseEntity = findBaseEntityById(entityType, entityId); 

Ich gehe davon aus, dass BaseDao<T>.findBaseEntityById()T Typ zurückgeben muss. Wenn nicht, sollte es! :-)

0

Sie hoffen, dass Ihr "T extends BaseEntity" BaseEntity abdeckt und es könnte überall dort weitergegeben werden, wo Sie 'T' als Parameter setzen. Nicht so ein Glück, mein Freund. Bitte überprüfen Sie Ihr Verständnis von Generika.