2

ジェネリックを使用してコマンドパターンのかなり単純な実装を実装しようとしています

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) in java.util.Map,CommandHandler> は適用できません (java.lang.Class,CommandHandler)

コンパイラが commandMap.put( commandClass, handler ); で型を推測できない理由がわかりません。

どんな助けでも大歓迎です。

4

2 に答える 2

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);
}
于 2013-09-27T02:30:11.627 に答える
1

あなたのマップは宣言されています:

Map< Class<Command>,CommandHandler<Command>>

しかし、次のタイプの値を入れようとします:

Class<H> commandClass, CommandHandler<H> handler

どこ<H extends Command>

おそらく、型の CommandExecutionService にジェネリック型を追加<T extends Command>し、マップを次のように宣言する必要があります。

Map< Class<T>, CommandHandler<T>>

そして方法:

public void addCommandHandler (Class<T> commandClass, CommandHandler<T> handler) { ... }
于 2013-09-27T01:31:05.493 に答える