2012-03-07 144 views
0

信令協議經常使用具有明確定義的整數值的枚舉類型。例如。Java:使用反射實例化來自數字的枚舉

public enum IpHdrProtocol { 

TCP(6), 
SCTP(132), 
MPLS(137); 
int Value; 

IpProtocol(int value) { 
    Value = value; 
} 

我試圖找到反序列化只用枚舉類類型和實例的整數值,該值的其相應的枚舉類型的一種方式。

如果這需要將靜態getEnumFromInt(int)函數添加到每個枚舉中,那麼如何定義此「接口」以便枚舉作者可以確保它們的枚舉可以被序列化。

這怎麼能做到最好?

回答

1

不知道你想能走多遠,但這裏是一些非常醜陋的代碼是你的枚舉的創傷更小:

的所有代碼不能編譯
public class Main { 

    public enum IpHdrProtocol { 

     TCP(6), SCTP(132), MPLS(137); 
     int Value; 

     IpHdrProtocol(int value) { 
      Value = value; 
     } 
    } 

    public static void main(String[] argv) throws NoSuchMethodException, IllegalArgumentException, InvocationTargetException, 
      IllegalAccessException, SecurityException, NoSuchFieldException { 
     System.err.println(getProtocol(6)); 
     System.err.println(getProtocol(132)); 
     System.err.println(getProtocol(137)); 
    } 

    private static IpHdrProtocol getProtocol(int i) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, 
      SecurityException, NoSuchFieldException { 
     Field f = IpHdrProtocol.class.getDeclaredField("Value"); 
     Method m = IpHdrProtocol.class.getMethod("values", null); 
     Object[] invoke = (Object[]) m.invoke(null, null); 
     for (Object o : invoke) { 
      if (!f.isAccessible()) { 
       f.setAccessible(true); 
      } 
      if (((Integer) f.get(o)).intValue() == i) { 
       return (IpHdrProtocol) o; 
      } 
     } 
     return null; 
    } 

    } 
+0

這就是我想要的並基於此實現了一個解決方案。實際上,我首先創建了一個反序列化程序對象,它查詢了您所顯示的枚舉類,但創建了一個整數值和相應的枚舉實例值的映射。當我使用它來反序列化時,我只需在地圖上查找。 Simples。所有被問及特定枚舉類的問題都是它實現了一個支持getIntValue()的簡單接口,這非常乾淨。 – 2012-03-07 13:55:11

0

第一。一種解決方案是以下(如果這是你想要的):

public enum IpHdrProtocol { 

    TCP(6), 
    SCTP(132), 
    MPLS(137); 
    int Value; 

    IpHdrProtocol(int value) { 
     Value = value; 
    } 

    public static IpHdrProtocol getFromInt(int val) { 
     for(IpHdrProtocol prot : values()) { 
      if(prot.Value == val) { 
       return prot; 
      } 
     } 

     return null; 
    } 
} 
+0

應該'getFromInt'是靜態的嗎? – gigadot 2012-03-07 12:27:26

+0

是的......所以你可以使用分類器而不是實例來調用方法(你想獲得實例,你已經沒有它)。 – 2012-03-07 12:32:06

+0

我想定義一個接口,所以枚舉作者可以確保他們的枚舉可以序列化,但靜態函數不允許這樣做。任何想法如何解決這個問題? – 2012-03-07 12:46:39

1

如果你在談論Java的內置序列化,枚舉已實現Serializable接口。只需序列化枚舉值,就完成了。

如果你想建立自己的序列化,你可以只讀取和寫入的int值,並獲得相應的枚舉值回加給你的枚舉反序列化時:

public static IpHdrProtocol valueOf(int value) { 
    for (IpHdrProtocol p : values()) { 
    if (p.Value == value) return p; 
    } 
    return null; // or throw exception 
} 
+0

我想定義一個接口,讓枚舉作者可以確保他們的枚舉可以序列化,但靜態函數不允許這樣做。任何想法如何解決這個問題? – 2012-03-07 12:46:47

+0

+1表示「或拋出異常」。好的,Jorn :)。 – jqno 2012-03-07 12:48:48