问题
Below is the failed attempt which I came up with, referring to Java Generic Enum class using Reflection.
Wanted to find a better way to do this. Couple of issues I find with this approach:
Each and every time I need to pass the class type. Example - EnumUtility.fromKey(Country.class, 1)
fromSet is duplicated in both City and Country
public enum City implements BaseEnumInterface {
TOKYO(0), NEWYORK(1);
private final int key;
public static Set<Integer> fromValue(Set<City> enums) {
return enums.stream().map(City::getKey).collect(Collectors.toSet());
}
public int getKey() {
return key;
}
private City(int key) {
this.key = key;
}
}
public enum Country implements BaseEnumInterface {
USA(0), UK(1);
private final int key;
public static Set<Integer> fromSet(Set<Country> enums) {
return enums.stream().map(Country::getKey).collect(Collectors.toSet());
}
public int getKey() {
return key;
}
private Country(int key) {
this.key = key;
}
}
public class EnumUtility {
public static <E extends Enum<E> & BaseEnumInterface> E fromKey(Class<E> enumClass, Integer key) {
for (E type : enumClass.getEnumConstants()) {
if (key == type.getKey()) {
return type;
}
}
throw new IllegalArgumentException("Invalid enum type supplied");
}
public static <E extends Enum<E> & BaseEnumInterface> Set<Integer> fromSet(Class<E> enumClass, Set<E> enums) {
return enums.stream().map(BaseEnumInterface::getKey).collect(Collectors.toSet());
}
}
interface BaseEnumInterface {
int getKey();
}
public class EnumTester {
public static void main(String args[]) {
System.out.println(EnumUtility.fromKey(Country.class, 1));
}
}
回答1:
There is no way to avoid passing in the enum class to fromKey. How else would you know which enum constants to check for the requested key? Note: The second parameter in that method should be of type int
, not Integer. Using ==
on Integer instances will not compare numeric values, it will compare object references!
EnumUtility.fromSet should work fine, so each enum class does not need a fromSet method at all. Note that EnumUtility.fromSet does not need a Class argument at all, and in fact your code is not using that parameter.
来源:https://stackoverflow.com/questions/43895415/java-generic-enum-functionality-using-java-8-default-methods-and-utility-class