这可能看起来与其他一些问题相似,但到目前为止我还没有找到解决方案。
我使用反射来解析我的json到不同的类,它节省了我编写类特定解析代码的大量精力,所有的int, long, string和calendar等都很容易处理,但现在我发现自己在Enum特定类型的地狱
类似:
else if (field.getType().isAssignableFrom(TransactionType.class)){
field.set(representation, TransactionType.fromInt(Integer.parseInt(value, 10)));
}
问题是枚举在JSON中存储为整数,当我不知道具体是什么枚举时,我找不到一种通用的方法来解析或将这些整数转换回枚举,并且我有相当多的枚举,因此70%的解析代码现在专门用于检查枚举类型…
是否有一种方法,当只给定field. gettype ().isEnum() == true时,将int值解析为该字段的enum类型
枚举类型声明为:
public static enum TransactionType{
cashback(0),deposit(1),withdraw(2),invitation(3);
public int code;
TransactionType(int code){
this.code = code;
}
private final static TransactionType[] map = TransactionType.values();
public static TransactionType fromInt(int n){
return map[n];
}
}
JSON可能有点复杂,但enum相关字段的格式如下:
{transactionType: 1, someOtherEnumType: 0}
根据提供的信息,我将如何处理这个问题。使用位于枚举类型之外的helper方法,该方法可以转换实现某些接口的任何枚举类型。
public static interface Codeable {
public int getCode();
}
public static enum TransactionType implements Codeable {
cashback(0),deposit(1),withdraw(2),invitation(3);
public int code;
TransactionType(int code) {
this.code = code;
}
@Override
public int getCode() {
return code;
}
}
public static <T extends Codeable> T fromCodeToEnum(int code, Class<T> clazz) {
for(T t : clazz.getEnumConstants()) {
if(t.getCode() == code) {
return t;
}
}
return null;
}
public static void main(String [] args) {
TransactionType type = fromCodeToEnum(1, TransactionType.class);
System.out.println(type); // deposit
}
Edit:当然,您也可以直接获取枚举值并遍历它们。
public static TransactionType findTransactionTypeByCode(int code) {
for(TransactionType t : TransactionType.values()) {
if(t.getCode() == code) {
return t;
}
}
return null;
}
Java不支持从文字到值的隐式强制转换。
Java中的enum有方法ordinal()
,它返回int
的值。
返回该枚举常量的序数(其在枚举声明中的位置,其中>初始常量被赋值为0的序数)。
不安全的解决方案
if(field.getType().isEnum()) {
Object itemInstance = field.getType().getEnumConstants()[ordinal];
}
无论如何,当它被设计为API的一部分时,不建议我们使用它。
对于这种情况,建议在enum的定义中定义。enum MyEnum {
ITEM(1);
private final int index;
MyEnum(int index) {
this.index;
}
}
然后您应该实现额外的逻辑来序列化和反序列化,例如基于具有默认方法的接口。
interface SerializableEnum<E extends Enum<E>> {
Class<E> getType();
default E valueOf(int ordinal) {
return getType().getEnumConstants()[ordinal];
}
}
请注意,最好的解决方案是通过名称而不是通过数字来序列化枚举。
class . getenumconstants()就是你需要的。
Class<?> cls = field.getType();
if (cls.isEnum()) {
field.set(representation,
cls.getEnumConstants()[Integer.parseInt(value, 10)]);
}