Mr Robot
Mr Robot

Reputation: 21

Generics applied on interface Java

I tried to write this interface

@SuppressWarnings({"unchecked", "rawtypes"})
public interface Command<T extends Enum<T> & Command> {
    default public T getCommand(String cmd) {
         final Class<? extends Enum> enumType = T.class;
         return T.valueOf(enumType, cmd);
    }
}

but doesn't compile. Why?

I want use this interface to implement Enum like this:

public enum RestCommand implements Command<RestCommand> {
    GET, PUT, POST, DELETE;
}

Upvotes: 1

Views: 57

Answers (1)

Andy Turner
Andy Turner

Reputation: 140318

Because of type erasure, you can't invoke methods on type variables like you can with static members of classes:

String.class  // OK
T.class       // Compiler error, because T is unknown at compile time.

You can work around this by passing in enumType as a parameter to the method:

public interface Command<T extends Enum<T> & Command<T>> {
  default public T getCommand(String cmd, Class<T> enumType) {
    return Enum.valueOf(enumType, cmd);
  }
}

But it's not really clear what you gain through this: in your enum, you now need an instance of the enum to access an instance of the enum:

GET.getCommand("POST", RestCommand.class);

which is awkward: you shouldn't need a GET to get the POST.

Basically, the enum shouldn't implement the Command interface; it's really a CommandFactory (or something like that):

class RestCommandFactory implements CommandFactory<RestCommand> {}

since you're using it to get the instances of RestCommand.

Upvotes: 2

Related Questions