2012-03-07 312 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