Java:使用反射实例化来自数字的枚举
信令协议经常使用具有明确定义的整数值的枚举类型。例如。Java:使用反射实例化来自数字的枚举
public enum IpHdrProtocol {
TCP(6),
SCTP(132),
MPLS(137);
int Value;
IpProtocol(int value) {
Value = value;
}
我试图找到反序列化只用枚举类类型和实例的整数值,该值的其相应的枚举类型的一种方式。
如果这需要将静态getEnumFromInt(int)函数添加到每个枚举中,那么如何定义此“接口”以便枚举作者可以确保它们的枚举可以被序列化。
这怎么能做到最好?
不知道你想能走多远,但这里是一些非常丑陋的代码是你的枚举的创伤更小:
的所有代码不能编译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;
}
}
第一。一种解决方案是以下(如果这是你想要的):
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;
}
}
应该'getFromInt'是静态的吗? – gigadot 2012-03-07 12:27:26
是的......所以你可以使用分类器而不是实例来调用方法(你想获得实例,你已经没有它)。 – 2012-03-07 12:32:06
我想定义一个接口,所以枚举作者可以确保他们的枚举可以序列化,但静态函数不允许这样做。任何想法如何解决这个问题? – 2012-03-07 12:46:39
如果你在谈论Java的内置序列化,枚举已实现Serializable接口。只需序列化枚举值,就完成了。
如果你想建立自己的序列化,你可以只读取和写入的int值,并获得相应的枚举值回加给你的枚举反序列化时:
public static IpHdrProtocol valueOf(int value) {
for (IpHdrProtocol p : values()) {
if (p.Value == value) return p;
}
return null; // or throw exception
}
我想定义一个接口,让枚举作者可以确保他们的枚举可以序列化,但静态函数不允许这样做。任何想法如何解决这个问题? – 2012-03-07 12:46:47
+1表示“或抛出异常”。好的,Jorn :)。 – jqno 2012-03-07 12:48:48
这就是我想要的并基于此实现了一个解决方案。实际上,我首先创建了一个反序列化程序对象,它查询了您所显示的枚举类,但创建了一个整数值和相应的枚举实例值的映射。当我使用它来反序列化时,我只需在地图上查找。 Simples。所有被问及特定枚举类的问题都是它实现了一个支持getIntValue()的简单接口,这非常干净。 – 2012-03-07 13:55:11