Java: создание экземпляра перечисления из числа с помощью отражения - PullRequest
0 голосов
/ 07 марта 2012

Протоколы сигнализации часто используют перечисляемые типы, которые имеют четко определенные целочисленные значения. Э.Г.

public enum IpHdrProtocol {

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

IpProtocol(int value) {
    Value = value;
}

Я пытаюсь найти способ десериализации такого значения для соответствующего ему перечислимого типа, используя только тип класса Enum и целочисленное значение для экземпляра.

Если для этого требуется, чтобы функция Static getEnumFromInt (int) была добавлена ​​к каждому перечислению, то как можно определить этот «интерфейс», чтобы авторы перечисления могли обеспечить сериализацию их перечислений.

Как это лучше всего сделать?

Ответы [ 3 ]

1 голос
/ 07 марта 2012

Если вы говорите о встроенной сериализации Java, Enums уже реализует интерфейс Serializable. Просто сериализуйте значение enum, и все готово.

Если вы хотите создать свою собственную сериализацию, вы можете просто прочитать и записать значение int и получить обратно соответствующее значение перечисления при десериализации, добавив это в ваше перечисление:

public static IpHdrProtocol valueOf(int value) {
  for (IpHdrProtocol p : values()) {
    if (p.Value == value) return p;
  }
  return null; // or throw exception
}
1 голос
/ 07 марта 2012

Не знаю, как далеко вы хотите зайти, но вот довольно уродливый код, который будет менее инвазивен в вашем перечислении:

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 голосов
/ 07 марта 2012

Прежде всего ваш код не компилируется.Решение будет следующее (если это то, что вы хотите):

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