2017-01-22 5 views
3

Ich kann keine Lösung für mein Problem finden. In beiden Fällen bekomme ich einen Kompilierfehler. Irgendwelche Hilfe, damit es funktioniert?Kompilierfehler mit verschachtelten Generika und Vererbung

Fall 1:

public class Entity<T extends EntityHandler<Entity>> { 

    protected T handler; 

    public void remove() { 
     for (Entity entity : handler.getEntities()) { 
      // do stuff 
     } 

     handler.saveEntity(this); 
    } 
} 

public class Player<T extends PlayerHandler<Player>> extends Entity</*error here*/T> {} 

public class EntityHandler<T extends Entity> { 

    private List<T> entities; 

    public void saveEntity(T entity) { 
     // do stuff 
    } 

    public List<T> getEntities() { 
     return entities; 
    } 
} 

public class PlayerHandler<T extends Player> extends EntityHandler<T> {} 

Fehler: Typargument T nicht innerhalb der Grenzen des Typ-Variable T

Fall 2:

public class Entity<T extends EntityHandler<? extends Entity>> { 

    protected T handler; 

    public void remove() { 
     for (Entity entity : handler.getEntities()) { 
      // do stuff 
     } 

     handler.saveEntity(/*error here*/this); 
    } 
} 

public class Player<T extends PlayerHandler<? extends Player>> extends Entity<T> {} 

public class EntityHandler<T extends Entity> { 

    private List<T> entities; 

    public void saveEntity(T entity) { 
     // do stuff 
    } 

    public List<T> getEntities() { 
     return entities; 
    } 
} 

public class PlayerHandler<T extends Player> extends EntityHandler<T> {} 

Fehler: inkompatible Typen: Entity nicht sein kann konvertiert, um # 1 von? extends Entity

Frage: Warum wird die erweiterte for-Schleife kompiliert und es wirft keinen Kompilierungsfehler ähnlich dem obigen?

+0

Würdest du den EntityHandler nicht generisch machen? Aber und abstrakt, das hat einen Setter für Entität? – efekctive

+0

öffentliche Klasse Player > erweitert Entität ist wirklich eingeschränkt in der Art und Weise, wie Sie die Dinge verschieben können – efekctive

Antwort

2

Im ersten Fall haben Sie Fehler an falscher Stelle markiert. Es ist hier:

public class Player<T extends PlayerHandler<Player>> extends Entity<T //here> {} 

Error:(20, 73) java: type argument T is not within bounds of type-variable T

Und es ist ganz einfach - Entity nur mit Klassen parametriert werden können, die EntityHandler verlängern.

Im zweiten Fall kompiliert Ihre for wegen erasure, so im Grunde getEntities gibt nur Liste von etwas zurück.

Wie für saveEntity Fehler, dort versuchen Sie, capture<? extends Entity zu übergeben, aber Methode erwartet, Entity<T> zu haben, was nicht erlaubt ist.

+0

Ich schätze Ihre Hilfe, aber was ich wollte, war eine Lösung, um meinen Code ohne Fehler zu machen. – Grimerlin

+0

In der Theorie erweitert das erste T PlayerHandler, der EntityHandler erweitert. Dies sollte für Entity (20, 73 Fehler) ausreichen. Vielleicht nimmt der Compiler an, dass PlayerHandler dieses Kriterium nicht erfüllt – efekctive

+0

Sorry, aber ich habe nicht verstanden, was ich im Code ändern muss. Ich habe den Fehler an der richtigen Stelle markiert, wie Sie vorgeschlagen haben. – Grimerlin

0

änderte ich den Code in Fall 1 bis

public class Entity<T extends EntityHandler<Entity>> { 

protected T handler; 

public void remove() { 
    for (Entity entity : handler.getEntities()) { 
     // do stuff 
    } 

    handler.saveEntity(this); 
} 
} 


public class EntityHandler<T extends Entity> { 

private List<T> entities; 

public void saveEntity(T entity) { 
    // do stuff 
} 

public List<T> getEntities() { 
    return entities; 
} 
} 

public class PlayerHandler<T extends Player> extends EntityHandler</*error here*/T> {} 

public class Player<T extends PlayerHandler<?>> extends Entity<EntityHandler<Entity>>{} 

und ich erhalte keine Compiler-Fehler oder Warnung. In der Eclipse-Version arbeiten: Juno Service Release 2 und JavaSE-1.7.

+0

Das ist keine gültige Lösung. Das T in der Player-Klasse würde keinen Sinn ergeben, da der Handler ein EntityHandler ist und ich einen PlayerHandler brauche. – Grimerlin

+0

Ok, nächster Versuch: 'öffentliche Klasse PlayerHandler erweitert EntityHandler >> öffentliche Klasse Player > erweitert PlayerHandler >> {}', die den Handler machen würde a Playerhandler – Alex

+0

'öffentliche Klasse PlayerHandler erweitert EntityHandler öffentliche Klasse Player > erweitert PlayerHandler {}'. Tut mir leid, ich habe es im obigen Kommentar nicht bereinigt. – Alex