java泛型编译器在泛型方法上的怪异行为

java泛型编译器在泛型方法上的怪异行为,java,generics,Java,Generics,我正在尝试使用泛型实现命令paten的一个非常简单的实现 public abstract class Command { } public interface CommandHandler<H extends Command> { boolean isActive(); void execute( H command ); } public class CommandExecutionServiceImpl implements Command

我正在尝试使用泛型实现命令paten的一个非常简单的实现

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 );

    }
公共抽象类命令{
}
公共接口命令处理程序{
布尔isActive();
无效执行(H命令);
}
公共类CommandExecutionServiceImpl实现CommandExecutionService{
私有映射commandMap;
public CommandExecutionServiceImpl(){
commandMap=newhashmap();
}
@凌驾
public void executeCommand(命令){
CommandHandler=commandMap.get(command.getClass());
handler.execute(命令);
}
@凌驾
公共布尔值isActive(命令){
返回false;
}
@凌驾
public void addCommandHandler(类commandClass,CommandHandler处理程序){
put(commandClass,handler);
}
编译器因错误而失败

编译失败 CommandExecutionServiceImpl.java:[36,12]在java.util.Map、CommandHandler>中放置(java.lang.Class、CommandHandler)不能应用于(java.lang.Class、CommandHandler)

我不明白为什么编译器不能推断commandMap.put(commandClass,handler)的类型

任何帮助都将不胜感激。

您的地图声明:

Map< Class<Command>,CommandHandler<Command>>
Map
但您尝试将以下类型的值放入:

Class<H> commandClass, CommandHandler<H> handler
Class命令类,命令处理程序
其中

也许您应该向CommandExecutionService添加一个泛型类型,类型为
,并将映射声明为:

Map< Class<T>, CommandHandler<T>>
Map
方法是:

public void addCommandHandler (Class<T> commandClass, CommandHandler<T> handler) { ... }
public void addCommandHandler(类commandClass,CommandHandler){…}
您的地图已声明:

Map< Class<Command>,CommandHandler<Command>>
Map
但您尝试将以下类型的值放入:

Class<H> commandClass, CommandHandler<H> handler
Class命令类,命令处理程序
其中

也许您应该向CommandExecutionService添加一个泛型类型,类型为
,并将映射声明为:

Map< Class<T>, CommandHandler<T>>
Map
方法是:

public void addCommandHandler (Class<T> commandClass, CommandHandler<T> handler) { ... }
public void addCommandHandler(类commandClass,CommandHandler){…}

看起来您希望在映射的键和值之间建立一种通用关系。如果支持这种关系,则可能如下所示:

private <H extends Command> Map<Class<H>, CommandHandler<H>> commandMap;
私有映射commandMap;
但这显然是不允许的。解决方法是使用Josh Bloch的模式:


private Map看起来您希望在映射的键和值之间建立一种通用关系。如果支持这种关系,则可能如下所示:

private <H extends Command> Map<Class<H>, CommandHandler<H>> commandMap;
私有地图命令映射;
但这显然是不允许的。解决方法是使用Josh Bloch的模式:


private MapA
Map
只能有一个条目(如果计算
null
键,则两个条目)。
Map
只能有一个条目(如果计算
null
键,则两个条目).实际上,我不希望在映射中的键值之间建立通用关系,而是希望在方法签名中的command类和commandhandler类型变量之间建立一种关系,并且这种关系可以正常工作。这里的问题是,编译器(我认为)无法(从这里)从H extends命令强制转换或推断:put(java.lang.class,commandhandler)在java.util.Map中不能应用于(java.lang.Class,CommandHandler)H extends命令,因此在映射中放置类型安全,我必须像……`commandMap.put((Class)commandClass,(CommandHandler)handler)这样显式转换;`我不确定我是否理解你的评论。如果你使用
mapi如果我使用
mapfactual,我不希望在映射中的键值之间建立泛型关系,而是希望在方法签名中的command类和commandhandler类型变量之间建立关系,这样就可以了。这里的问题是编译器不能(我认为)在这里从H extends命令强制转换或推断:java.util.Map中的put(java.lang.Class,CommandHandler)不能应用于(java.lang.Class,CommandHandler)H extends命令,因此在映射中放置类型安全,我必须显式转换为……`commandMap.put((Class)commandClass,(CommandHandler)handler)我不确定我是否理解你的评论。如果你使用
Map如果我使用
Map