Search code examples
javaserializationbinary-serialization

Java: instantiating an enum from a number using reflection


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?


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