Since there is no relationship between static methods and class type parameters that describes how instances are parameterized, you must make the general static method common. The hard part is to get declarations to describe all the necessary restrictions. And since this answer has already been explained, you need to specify the aa Class parameter, since otherwise the implementation has no chance to get real arguments like:
public interface DbValuesEnumIface<ID, T extends Enum<T>> { public static <ID, T extends Enum<T>&DbValuesEnumIface<ID,T>> T fromId(ID id, Class<T> type) { if (id == null) { return null; } for (T en : type.getEnumConstants()) { if (en.getId().equals(id)) { return en; } } throw new NoSuchElementException(); } ID getId(); String getDescriptionKey(); }
Note that the parameters of the static method type are independent of the class type parameter. You might consider giving them different names for clarity.
So, given the example enum Statuses implements DbValuesEnumIface<Integer,Statuses> , you can use a method like Statuses status = DbValuesEnumIface.fromId(42, Statuses.class);
Note that for default methods, you can access the actual type, since the method providing the enum type will be provided by the implementation. You only need to declare a method in the interface :
public interface DbValuesEnumIface<ID, T extends Enum<T>&DbValuesEnumIface<ID,T>> { public default T fromId(ID id) { if (id == null) { return null; } for (T en : getDeclaringClass().getEnumConstants()) { if (en.getId().equals(id)) { return en; } } throw new NoSuchElementException(); } Class<T> getDeclaringClass();
However, the obvious drawback is that you need the target instance to call the method, i.e. Statuses status = Statuses.SOME_CONSTANT.fromId(42);
source share