[英]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<?> cls = field.getType();
if (cls.isEnum()) {
field.set(representation,
cls.getEnumConstants()[Integer.parseInt(value, 10)]);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.