0

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?

Howard May
  • 6,639
  • 9
  • 35
  • 47

3 Answers3

1

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

    }
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • This is what I want and have implemented a solution based on this. In fact I first create a de-serializer object which interrogates the enum class as you have shown but creates a map of integer values and corresponding enum instance values. When I use this to de-serialize I then simply have to a lookup in the map. Simples. All that is asked of a specific enum class is that it implements a simple Interface supporting getIntValue(), this is pretty clean. – Howard May Mar 07 '12 at 13:55
1

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
}
Jorn
  • 20,612
  • 18
  • 79
  • 126
  • I would like to define an interface so enum authors can ensure their enums can be serialized but static functions dont allow this. Any ideas how to work around this? – Howard May Mar 07 '12 at 12:46
0

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