在Java反射中将int转换为Enum



这可能看起来与其他一些问题相似,但到目前为止我还没有找到解决方案。

我使用反射来解析我的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)]);
}

相关内容

  • 没有找到相关文章