簡體   English   中英

在Java反射中將int轉換為Enum

[英]Converting int to Enum in Java reflection

這可能看起來與其他一些問題相似,但到目前為止,我還沒有找到解決方案。

我正在使用反射將JSON解析為不同的類,並且省去了編寫特定於類的解析代碼的工作,所有int,long,string和Calendars等都易於處理,但是現在我發現自己陷入了困境枚舉特定類型的地獄

就像是:

else if (field.getType().isAssignableFrom(TransactionType.class)){
    field.set(representation, TransactionType.fromInt(Integer.parseInt(value, 10)));
}

問題是枚舉在JSON中存儲為整數,並且當我不知道具體是什么枚舉時,我找不到一種通用的方法來解析或將這些整數轉換回枚舉,而且我有很多枚舉,因此我現在有70%的解析代碼專用於檢查枚舉類型...

有一種方法,僅給定field.getType()。isEnum()== true,就可以將int值解析為該字段的枚舉類型

枚舉類型聲明為:

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可能有點復雜,但是與枚舉相關的字段的格式為:

{transactionType: 1, someOtherEnumType: 0}

鑒於提供的信息,以下是我將如何批准的方法。 使用位於枚舉類型之外的幫助程序方法,該方法可以轉換實現某些接口的任何枚舉類型。


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
}

編輯:當然,您也可以只獲取枚舉值並通過它們進行迭代。 它可以放置在您想要的任何地方。

public static TransactionType findTransactionTypeByCode(int code) {

    for(TransactionType t : TransactionType.values()) {
        if(t.getCode() == code) {
            return t;
        }
    }
    return null;
}

Java不支持從文字到值的隱式轉換。

然后,Java中的枚舉具有方法ordinal() ,該方法返回int值。

返回此枚舉常量的序數(其在枚舉聲明中的位置,其中> initial常量被分配為零序數)。

不安全的解決方案

if(field.getType().isEnum()) {
  Object itemInstance = field.getType().getEnumConstants()[ordinal];
}

但是,不建議我們將它設計為API的一部分。

對於這種情況的建議是在枚舉的定義中進行定義。

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)]);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM