3

I can't figure out a solution to my problem. In both of these cases I get a compile error. Any help to make it work?

Case 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> {}

Error: type argument T is not within bounds of type-variable T

Case 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> {}

Error: incompatible types: Entity cannot be converted to capture#1 of ? extends Entity

Question: why does the enhanced for loop compile and it doesn't throw a compile error similar to the one above?

Grimerlin
  • 31
  • 5
  • Would you consider make EntityHandler not generic? but and abstract that has a setter for Entity? – bichito Jan 22 '17 at 23:45
  • public class Player> extends Entity is really constrained in the way you can shift things around – bichito Jan 22 '17 at 23:46

2 Answers2

2

In first case you've marked error in wrong place. It's here:

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

And it's quite easy - Entity can be parameterized only with classes which extend EntityHandler.

In second case your for compiles because of erasure, so basically getEntities returns just List of something.

As for saveEntity error, there you are trying to pass capture<? extends Entity but method expects to have Entity<T>, which is not allowed.

Community
  • 1
  • 1
Divers
  • 9,531
  • 7
  • 45
  • 88
  • I appreciate your help, but what I wanted was a solution to make my code work with no errors. – Grimerlin Jan 22 '17 at 20:44
  • In theory the first T extends PlayerHandler which extends EntityHandler. This should suffice for Entity (20, 73 error). Maybe the compiler assumes that PlayerHandler does not meet that criteria – bichito Jan 22 '17 at 21:16
  • Sorry but I didn't understand what I have to change in the code. I marked the error in the right place, as you suggested. – Grimerlin Jan 22 '17 at 21:38
0

I changed the code in case 1 to

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>>{}

and I get no compiler error or warning. Working in Eclipse Version: Juno Service Release 2 and JavaSE-1.7.

Alex
  • 779
  • 7
  • 15
  • That's not a valid solution. The T in the Player class would make no sense because the handler will be an EntityHandler and I need a PlayerHandler. – Grimerlin Jan 22 '17 at 21:56
  • Ok, next try: 'public class PlayerHandler extends EntityHandler>> public class Player> extends PlayerHandler>>{}' that would make the handler a Playerhandler – Alex Jan 22 '17 at 22:19
  • 'public class PlayerHandler extends EntityHandler public class Player> extends PlayerHandler{}'. Sorry I didn't cleaned it up in the above comment. – Alex Jan 22 '17 at 22:26
  • That is even worse. You are extending PlayerHandler to Player (Player should extend Entity) and I need to pass the T to the super class. – Grimerlin Jan 22 '17 at 23:31