带有“扩展”的Java泛型

时间:2011-10-26 11:36:50

标签: java generics

而不是使用if / else我想使用map来获得具体的实现。

我想使用泛型来声明处理特定实体的特定实体处理程序,但我遇到的问题是处理程序只接受我的实体接口的扩展。代码如下所示:

private Map<Class<IEntity>, IEntityHandler> handlers;

public void callingMethod(IModel model) {
  for (IEntity entity : model.getObjects()) {
    // handle accepts just IDevice and not IEntity !
    handlers.get(entity).handle(entity);
  }
}

public interface IEntityHandler<T extends IEntity> {
  handle(T entity);
}

public class DeviceHandler implements IEntityHandler<IDevice> {
  @Override
  public void handle(IDevice deviceEntity) {
    // do something
  }
}

如何获得IEntity所需的句柄方法? IDevice从IEntity扩展。

5 个答案:

答案 0 :(得分:1)

声明你映射为:

Map<Class<T extends IEntity>, IEntityHandler> handlers.

答案 1 :(得分:1)

首先,您需要更改此行...

handlers.get(entity).handle(entity);

到此......

handlers.get(entity.getClass()).handle(entity);

然后,就像其他人所说的那样,最好将地图的Class<IEntity>类型参数更改为Class<? extends IEntity>,因为您希望将具体类映射到处理程序。

如果您这样做,您将不会收到错误。只有警告,因为地图中的IEntityHandler类型参数是原始类型。但是,如果您尝试将其更改为? extends IEntityHandlerIEntityHandler<? extends IEntity>,则在分配或填充地图时会出现编译错误。

因此,我建议您只需对上述内容进行更改(getClass()Class<? extends IEntity>),然后使用注释简单地禁止警告。只要您的Map正确填充了正确类的正确处理程序,您就不会遇到麻烦。

答案 2 :(得分:0)

private Map<? extends IEntity, ? extends IEntityHandler> handlers;

答案 3 :(得分:0)

private Map<Class<? extends IEntity>, ? extends IEntityHandler> handlers;

答案 4 :(得分:0)

我认为你的目标是(深呼吸)typesafe hetereogeneous container。但是,由于您要存储的对象本身是通用的,因此您需要使用super type tokens

我认为你需要通过重写顶部循环来引入然后驯服一个通配符:

for (IEntity entity: model.getObjects()) {
    handle(entity);
}

private <T extends IEntity> handle(T entity) {
    IEntityHandler<T> handler = ... get appropriate handler from THC ...
    handler.handle(entity);
}
但是,我不确定这一点。这是一个非常粗略的草图。