Skip to main content
fixed typos and improved formatting
Source Link
Holger
  • 300.9k
  • 43
  • 481
  • 827

Since there is no relationship between static methods and the class’class’s type parameters, which describe how instances are parameterized, you have to make the static method generic on its own. The tricky part is to get the declarations right to describe all needed constraints. And, as this answer already explained, you need to aadd a Class parameter, as otherwise, the implementation has no chance to get hands on the actual type arguments:

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(); } 
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 type parameters of the static method are independent from the class’class’s type parameter. You may consider giving them different names for clarity.

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();//no needed to implement it, inherited by java.lang.Enum ID getId(); String getDescriptionKey(); } 
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(); } //no needed to implement it, inherited by java.lang.Enum Class<T> getDeclaringClass(); ID getId(); String getDescriptionKey(); } 

Since there is no relationship between static methods and the class’ type parameters, which describe how instances are parameterized, you have to make the static method generic on its own. The tricky part is to get the declarations right to describe all needed constraints. And as this answer already explained, you need to a a Class parameter, as otherwise, the implementation has no chance to get hands on the actual type arguments:

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 type parameters of the static method are independent from the class’ type parameter. You may consider giving them different names for clarity.

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();//no needed to implement it, inherited by java.lang.Enum ID getId(); String getDescriptionKey(); } 

Since there is no relationship between static methods and the class’s type parameters, which describe how instances are parameterized, you have to make the static method generic on its own. The tricky part is to get the declarations right to describe all needed constraints. And, as this answer already explained, you need to add a Class parameter, as otherwise, the implementation has no chance to get hands on the actual type arguments:

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 type parameters of the static method are independent from the class’s type parameter. You may consider giving them different names for clarity.

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(); } //no needed to implement it, inherited by java.lang.Enum Class<T> getDeclaringClass(); ID getId(); String getDescriptionKey(); } 
added 1086 characters in body
Source Link
Holger
  • 300.9k
  • 43
  • 481
  • 827

Note that for default methods, it is possible to access the actual type, as a method providing the enum type will be provided by the implementation. You only have to declare the presence of the method within 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();//no needed to implement it, inherited by java.lang.Enum ID getId(); String getDescriptionKey(); } 

However, the obvious disadvantage is that you need a target instance to invoke the method, i.e. Statuses status = Statuses.SOME_CONSTANT.fromId(42);


Note that for default methods, it is possible to access the actual type, as a method providing the enum type will be provided by the implementation. You only have to declare the presence of the method within 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();//no needed to implement it, inherited by java.lang.Enum ID getId(); String getDescriptionKey(); } 

However, the obvious disadvantage is that you need a target instance to invoke the method, i.e. Statuses status = Statuses.SOME_CONSTANT.fromId(42);

Source Link
Holger
  • 300.9k
  • 43
  • 481
  • 827

Since there is no relationship between static methods and the class’ type parameters, which describe how instances are parameterized, you have to make the static method generic on its own. The tricky part is to get the declarations right to describe all needed constraints. And as this answer already explained, you need to a a Class parameter, as otherwise, the implementation has no chance to get hands on the actual type arguments:

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 type parameters of the static method are independent from the class’ type parameter. You may consider giving them different names for clarity.

So now, given you enum Statuses implements DbValuesEnumIface<Integer,Statuses> example, you can use the method like Statuses status = DbValuesEnumIface.fromId(42, Statuses.class);