我正在尝试使用泛型
实现命令patern的非常天真的实现public abstract class Command {
}
public interface CommandHandler<H extends Command> {
boolean isActive();
void execute( H command );
}
public class CommandExecutionServiceImpl implements CommandExecutionService {
private Map< Class<Command>,CommandHandler<Command>> commandMap;
public CommandExecutionServiceImpl(){
commandMap = new HashMap<Class<Command>, CommandHandler<Command>>();
}
@Override
public void executeCommand(Command command) {
CommandHandler<Command> handler = commandMap.get(command.getClass());
handler.execute(command);
}
@Override
public boolean isActive(Command command) {
return false;
}
@Override
public <H extends Command> void addCommandHandler(Class<H> commandClass, CommandHandler<H> handler) {
commandMap.put( commandClass, handler );
}
编译器失败,
编译失败 CommandExecutionServiceImpl.java:[36,12] put(java.lang.Class,CommandHandler)在java.util.Map,CommandHandler&gt;中不能应用于(java.lang.Class,CommandHandler)
我无法理解为什么编译器无法在commandMap.put(commandClass,handler)中推断出类型;
任何帮助都将不胜感激。
答案 0 :(得分:3)
看起来你想要地图的键和值之间的通用关系。如果支持它可能看起来像这样:
private <H extends Command> Map<Class<H>, CommandHandler<H>> commandMap;
但显然不允许这样做。解决方法是使用Josh Bloch的Typesafe Heterogeneous Container模式:
private Map<Class<? extends Command>, CommandHandler<? extends Command>> commandMap;
@Override
public <H extends Command> void executeCommand(H command) {
// addCommandHandler guarantees the safety of this unchecked cast
@SuppressWarnings("unchecked")
CommandHandler<H> handler = (CommandHandler<H>)commandMap.get(command.getClass());
handler.execute(command);
}
答案 1 :(得分:1)
您的地图已声明:
Map< Class<Command>,CommandHandler<Command>>
但您尝试输入类型的值:
Class<H> commandClass, CommandHandler<H> handler
其中<H extends Command>
也许你应该在类型为<T extends Command>
的CommandExecutionService中添加泛型类型,并将地图声明为:
Map< Class<T>, CommandHandler<T>>
和方法:
public void addCommandHandler (Class<T> commandClass, CommandHandler<T> handler) { ... }