在 GWT-RPC 中使用嵌套枚举

Posted

技术标签:

【中文标题】在 GWT-RPC 中使用嵌套枚举【英文标题】:Using a nested enum in 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 中,您的示例可以正常工作。 【参考方案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

它会起作用的!

【讨论】:

问题在于内部枚举的可见性。它可以很好地序列化外部枚举。这没有回答我的问题。

以上是关于在 GWT-RPC 中使用嵌套枚举的主要内容,如果未能解决你的问题,请参考以下文章

swift 学习- 22 -- 嵌套类型

如何将嵌套枚举作为关联值传递但隐藏嵌套枚举的初始化?

在 Swift 的嵌套循环中从特定索引枚举字符串

如何在 GraphQL 模式中定义嵌套枚举类型

通过泛型类中嵌套枚举的反射获取枚举值

SpringBoot入门教程:枚举嵌套分组