在使用两个接口声明泛型类型参数时,如何避免不必要的强制转换

时间:2013-04-23 22:02:19

标签: java generics type-safety

为什么我必须在以下代码中将命令显式地转换为C? 命令实现Runnable和Describable。

@Test
public <C extends Runnable & Describable> void testMapOfCommands() throws Exception
{
    Map<String, C> commands = Maps.newHashMap();
    for(Commands command : Commands.values())
    {
        commands.put(command.name(), (C) command);
    }
    //Use commands here (not relevant to my question):
    //CommandLineParser.withCommands(commands).parse("commit");
}

private enum Commands implements Runnable, Describable
{
    commit
    {
        @Override
        public void run()
        {
            System.out.println("COMMIT");
        }

        @Override
        public String description()
        {
            return "Commits something";
        }
    };
}

我想到的一个解决方法是引入扩展Runnable和Describable的ICommand:

public interface ICommand extends Runnable, Describable{}

但是我试图避免在已经有两种类型可用时引入新类型并且我已经有一个更复杂的Command类。我在这里抓稻草吗?

1 个答案:

答案 0 :(得分:6)

您所拥有的是command类型为Commands的对象。但由于您的泛型类型声明<C extends Runnable & Describable>,Java期望C同时为DescribableRunnable,但C不一定是Commands

这种特殊的测试方法并不适用于除Commands以外的任何其他方法,因此它不应该是通用的。这应该有效:

public void testMapOfCommands() throws Exception
{
    Map<String, Commands> commands = new HashMap<String, Commands>();
    for(Commands command : Commands.values())
    {
        commands.put(command.name(), command);
    }
}