How to avoid unnecessary cast when declaring a generic type parameter with two interfaces

StackOverflow https://stackoverflow.com/questions/16179940

  •  11-04-2022
  •  | 
  •  

문제

Why do I have to explicitly cast command to C in the following code? Commands implements both Runnable and 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";
        }
    };
}

One workaround I have in mind is to introduce ICommand that extends both Runnable and Describable:

public interface ICommand extends Runnable, Describable{}

but I'm trying to avoid having to introduce a new type when there already is two types readily available and I already have a Command class that's a bit more complex. Am I grasping for straws here?

도움이 되었습니까?

해결책

What you have is a command object that is of type Commands. But because of your generic type declaration <C extends Runnable & Describable>, Java expects C to be both Describable and Runnable, but C is not necessariy a Commands.

This particular test method isn't meant to work with anything but Commands, so it should not be generic. This should work:

public void testMapOfCommands() throws Exception
{
    Map<String, Commands> commands = new HashMap<String, Commands>();
    for(Commands command : Commands.values())
    {
        commands.put(command.name(), command);
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top