如何创建通用枚举转换器?
How to create generic enum converter?
我想写一个通用的class,可以像new EnumConverter(MyEnum.class);
一样使用
但是我必须写 class 才能与对 enum.values()
的通用调用一起使用吗?
public class EnumConverter {
public EnumConverter(Class<Enum<?>> type) {
this.type = type;
}
public EnumConverter convert(String text) {
//error: Type mismatch: cannot convert from element type capture#1-of ? to Enum<?>
for (Enum<?> candidate : type.getDeclaringClass().getEnumConstants()) {
if (candidate.name().equalsIgnoreCase(text)) {
return candidate;
}
}
}
}
你的return方法转换类型是错误的:应该是Enum
而不是EnumConverter
。然后你不必调用 getDeclaringClass()
而是使用你已经输入的 Class
。
我建议采用更通用的方法:
public static class EnumConverter<T extends Enum<T>>
{
Class<T> type;
public EnumConverter(Class<T> type)
{
this.type = type;
}
public Enum<T> convert(String text)
{
for (Enum<T> candidate : type.getEnumConstants()) {
if (candidate.name().equalsIgnoreCase(text)) {
return candidate;
}
}
return null;
}
}
您的问题不一致且代码无效:
1) this.type 未定义为字段
2) 你定义转换为 return EnumConverter
但 return 一个 Enum
到 return 来自文本的枚举的枚举值你不需要通用的东西。你只需使用:
Enum.valueOf(MyEnum.class, "TWO")
如果有人在寻找没有 for 循环的替代解决方案。
// classType is target Enum
public static Enum<?> toEnum(final Class<? extends Enum> classType, final Enum<?> enumObj) {
if (enumObj == null) {
return null;
} else {
return enumObj.valueOf(classType, enumObj + "");
}
用法:
TestEnum1 enum1 = (TestEnum1) toEnum(TestEnum1.class, TestEnum1.HELLO_ENUM);
以下内容与要求的 class 不同,但仍然比其他一些答案有所改进,因为它不会产生警告(java 11/IDEA 2020)
static <Dest extends Enum<Dest>> Dest
convertEnumStrict(final Class<Dest> destinationClassType, final Enum<?> sourceEnum) {
if (sourceEnum == null) {
return null;
}
return Dest.valueOf(destinationClassType, sourceEnum.name());
}
static <Dest extends Enum<Dest>> Dest
convertEnumOrNull(final Class<Dest> destinationClassType, final Enum<?> sourceEnum) {
try {
return convertEnumStrict(destinationClassType, sourceEnum);
} catch (IllegalArgumentException e) {
return null;
}
}
将两个最佳答案放在一起,你得到一个干净的衬里:
public <T extends Enum<T>> T getEnumValue(Class<T> type, String str) {
return Enum.valueOf(type, str);
}
我想写一个通用的class,可以像new EnumConverter(MyEnum.class);
但是我必须写 class 才能与对 enum.values()
的通用调用一起使用吗?
public class EnumConverter {
public EnumConverter(Class<Enum<?>> type) {
this.type = type;
}
public EnumConverter convert(String text) {
//error: Type mismatch: cannot convert from element type capture#1-of ? to Enum<?>
for (Enum<?> candidate : type.getDeclaringClass().getEnumConstants()) {
if (candidate.name().equalsIgnoreCase(text)) {
return candidate;
}
}
}
}
你的return方法转换类型是错误的:应该是Enum
而不是EnumConverter
。然后你不必调用 getDeclaringClass()
而是使用你已经输入的 Class
。
我建议采用更通用的方法:
public static class EnumConverter<T extends Enum<T>>
{
Class<T> type;
public EnumConverter(Class<T> type)
{
this.type = type;
}
public Enum<T> convert(String text)
{
for (Enum<T> candidate : type.getEnumConstants()) {
if (candidate.name().equalsIgnoreCase(text)) {
return candidate;
}
}
return null;
}
}
您的问题不一致且代码无效:
1) this.type 未定义为字段
2) 你定义转换为 return EnumConverter
但 return 一个 Enum
到 return 来自文本的枚举的枚举值你不需要通用的东西。你只需使用:
Enum.valueOf(MyEnum.class, "TWO")
如果有人在寻找没有 for 循环的替代解决方案。
// classType is target Enum
public static Enum<?> toEnum(final Class<? extends Enum> classType, final Enum<?> enumObj) {
if (enumObj == null) {
return null;
} else {
return enumObj.valueOf(classType, enumObj + "");
}
用法:
TestEnum1 enum1 = (TestEnum1) toEnum(TestEnum1.class, TestEnum1.HELLO_ENUM);
以下内容与要求的 class 不同,但仍然比其他一些答案有所改进,因为它不会产生警告(java 11/IDEA 2020)
static <Dest extends Enum<Dest>> Dest
convertEnumStrict(final Class<Dest> destinationClassType, final Enum<?> sourceEnum) {
if (sourceEnum == null) {
return null;
}
return Dest.valueOf(destinationClassType, sourceEnum.name());
}
static <Dest extends Enum<Dest>> Dest
convertEnumOrNull(final Class<Dest> destinationClassType, final Enum<?> sourceEnum) {
try {
return convertEnumStrict(destinationClassType, sourceEnum);
} catch (IllegalArgumentException e) {
return null;
}
}
将两个最佳答案放在一起,你得到一个干净的衬里:
public <T extends Enum<T>> T getEnumValue(Class<T> type, String str) {
return Enum.valueOf(type, str);
}