Question

Signalling Protocols make frequent use of Enumerated types which have well defined integer values. E.g.

public enum IpHdrProtocol {

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

IpProtocol(int value) {
    Value = value;
}

I am trying to find a way of de-serializing such a value to its corresponding Enumerated type using just the Enum Class type and the integer value for the instance.

If this requires a Static getEnumFromInt(int) function to be added to each enum then how can this 'interface' be defined so enum authors can ensure their enums can be serialized.

How can this best be done?

Was it helpful?

Solution

Not sure on how far you want to go, but here is some pretty ugly code to be the less invasive on your enum:

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

    }

OTHER TIPS

If you're talking about Java's built-in serialization, Enums already implement the Serializable interface. Just serialize the enum value, and you're done.

If you want to build your own serialization, you can just read and write the int value, and get the corresponding enum value back when deserializing by adding this to your enum:

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

First of all your code does not compile. A solution would be the following (if this is what you want):

 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;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top