Java Generics不能将通配符与通用T一起使用

时间:2017-11-23 08:09:44

标签: java generics inheritance

我有以下小界面:

public interface EntityController<T> {
    public void update( float elapsed, T applyTo );
}

我想以下列方式使用:

private Map<Class<? extends GameObject>, EntityController<?>> registeredControllers;
public EntityController<?> getController(GameObject o) {
    return registeredControllers.get(o.getClass());;
}
...
getController(myObj).update(elapsed, myObj);

最后一行给出了The method update(float, capture#1-of ?) in the type EntityController<capture#1-of ?> is not applicable for the arguments (float, GameObject)

的错误

为什么?基本上,我想要实现的目标如下: 我知道每个EntityController只负责处理一种特定类型的类。因此,在它的更新方法中,我总是要将GameObject强制转换为相应的类型,这很烦人,我猜也会产生某种开销?我认为泛型是解决问题的好方法,允许我以下列方式创建特定的控制器:

public class MyController implements EntityController<MyType> {
    public void update(float elapsed, MyType applyTo){}
}

为什么不可能?

1 个答案:

答案 0 :(得分:1)

简单地说,你不能为通配符类型赋值,因为实际的类型是未知的。因此,如果返回类型为EntityController<?>,则无法分配更新的第二个参数。

最简单(但不是100%类型安全)的解决方案是

private Map<Class<? extends GameObject>, EntityController<? extends GameObject>> registeredControllers;

@SuppressWarnings("unchecked")
public <T extends GameObject> EntityController<T> getController(T o) {
    return (EntityController<T>) registeredControllers.get(o.getClass());
}