【问题标题】:Using a nested enum in GWT-RPC在 GWT-RPC 中使用嵌套枚举
【发布时间】:2011-10-18 10:37:58
【问题描述】:

我有一个带有嵌套枚举的枚举(我想将其设为私有),但是当我这样做时,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;
    }
}

如果我从嵌套枚举中删除私有修饰符,那么代码就可以工作。为什么 GWT 不允许嵌套枚举的私有修饰符?有解决办法吗?

【问题讨论】:

  • 你试过让它静态吗?
  • 这真的很酷! JLS(第 8.9 节)明确指出“嵌套枚举类型是隐式静态的。允许将嵌套枚举类型显式声明为静态。”这不适用于嵌套在enums 中的enums 还是GWT 编译器中的一个小缺陷?
  • ...而 GWT 编译器仅使用 Eclipse 编译器 (ECJ) 来解析源代码并构建 AST。因此,要么 Eclipse 编译器有一个错误,即没有将枚举暴露为静态,要么 GWT 有一个错误,即没有为嵌套枚举推断静态标志(我会选择 ECJ,但这真的取决于他们的意图;它可能是设计使然)。
  • ....好吧,我觉得自己很愚蠢....以前的构建中有一些东西挂在上面,结果证明将其设为静态并没有什么不同...。回到图纸木板。对不起各位!
  • 您使用的是什么 GWT 版本?在 GWT 2.4.0 中,您的示例可以正常工作。

标签: java gwt enums gwt-rpc


【解决方案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;
        }
    }
}

这个例子和之前的例子很不一样。假设在 GWT-RPC 服务中使用 OuterClass。由于 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
    }
    

    它会起作用的!

    【讨论】:

    • 问题在于内部枚举的可见性。它可以很好地序列化外部枚举。这没有回答我的问题。
    猜你喜欢
    • 1970-01-01
    • 2010-10-22
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-12
    • 1970-01-01
    相关资源
    最近更新 更多