Использование вложенного перечисления в GWT-RPC

У меня есть перечисление с вложенным перечислением (которое я хочу сделать закрытым), но когда я это делаю, GWT сообщает мне, что вложенное перечисление не видно и генерирует исключение.

public enum OuterEnum {
    A(NestedEnum.X),
    B(NestedEnum.Y),
    C(NestedEnum.X);

    NestedEnum nestedValue;
    private OuterEnum(NestedEnum nv) { nestedValue = nv; }

    private enum NestedEnum {
        X, Y;
    }
}

Если я удалю частный модификатор из вложенного enum, тогда код работает. Почему GWT не разрешает частный модификатор для вложенных перечислений? Есть ли способ обхода?

Ответ 1

Сериализация работает просто отлично, по крайней мере, на примере, который вы предоставили. Все перечисления получают сериализацию/десериализацию следующим образом (GWT 2.4, 2.3, 2.2):

    public static OuterEnum instantiate(SerializationStreamReader streamReader) throws SerializationException {
            int ordinal = streamReader.readInt();
            OuterEnum[] values = OuterEnum.values();
            assert (ordinal >= 0 && ordinal < values.length);
            return values[ordinal];
}

    public static void serialize(SerializationStreamWriter streamWriter, OuterEnum instance) throws SerializationException {
            assert (instance != null);
            streamWriter.writeInt(instance.ordinal());
}

например. Мне не важно, что используется внутри. По сети передается только порядковый номер. Это означает, что в каком-то другом месте есть проблема, GWT просто не интересует, что внутри перечисления, потому что оно не передается по сети (перечисление должно быть неизменным, нет необходимости передавать его состояние). Я думаю, что ваша проблема может быть примерно такой:

public class OuterClass implements Serializable{

    private OuterEnum.NestedEnum nested;
    private OuterEnum outer;

    public enum OuterEnum {
        A(NestedEnum.X), B(NestedEnum.Y), C(NestedEnum.X);

        NestedEnum nestedValue;

        private OuterEnum(NestedEnum nv) {
            nestedValue = nv;
        }


        private enum NestedEnum {
            X, Y;
        }
    }
}

Этот пример ОЧЕНЬ отличается от предыдущего. Предположим, что OuterClass используется в службе GWT-RPC. Поскольку NestedEnum используется как поле OuterClass, GWT необходимо создать для него TypeSerializer. Но поскольку TypeSerializer является отдельным классом, он не имеет ЛЮБОГО доступа к NestedEnum (поскольку он является закрытым). Таким образом, компиляция терпит неудачу.

Это в основном единственный случай, когда ваш пример не будет работать. Могут быть некоторые ошибки в некоторых конкретных версиях GWT, но я на 100% уверен, что ваш пример работает в gwt 2.2-2.4.

Ответ 2

Это, вероятно, связано с JavaScript. Возможно/вероятно, что в переводе на JavaScript вложенный класс записывается как не-вложенный. Поэтому, если он является приватным, ничто другое не имеет к нему доступа. Обходной путь заключается не в том, чтобы сделать его закрытым, по умолчанию область действия должна работать нормально.

Ответ 3

Чтобы быть классом класса параметра RPC, он должен иметь пустой конструктор для сериализации. Поэтому я думаю, если вы добавите

private OuterEnum(){
// may be you should give a default value to nestedValue
}

Это сработает!