2011-10-18 59 views
10

我有一个枚举嵌套枚举(我想要私有),但是当我这样做时,GWT告诉我,嵌套的枚举不可见并引发异常。在GWT-RPC中使用嵌套枚举

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不允许嵌套枚举的私有修饰符?有没有解决方法?

+2

你有没有试过让它变成静态的? –

+0

这真的很酷! JLS(第8.9节)明确指出“嵌套枚举类型是隐式静态的,允许显式声明一个嵌套枚举类型为静态。”这不适用于嵌套在'enum'中的'enum',还是它在GWT编译器中的一个小缺陷? –

+0

...和GWT编译器只是使用Eclipse编译器(ECJ)来解析源代码并构建AST。所以无论Eclipse编译器有没有暴露枚举静态,或GWT有一个错误,不推断嵌套枚举的静态标志(我会去ECJ,但它确实取决于他们的意图是什么;它可能是通过设计)。 –

回答

2

序列化工作得很好,至少在你提供的例子中。所有枚举以下列方式进行序列化/反序列化(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。

0

这可能与JavaScript有关。在翻译成JavaScript的过程中,可能/很可能嵌套类被写为非嵌套类。因此,如果它是私人的,没有其他人可以访问它。解决方法是不要将其设为私有,默认范围应该可以正常工作。

+0

这是一个很好的观点,我没有想到这一点理想情况下,我希望它是私人的,但... – luketorjussen

-2

要成为RPC参数类类型,它必须具有用于序列化的空构造函数。 所以我觉得,如果你添加

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

很有效!

+0

问题是内部枚举的可见性,它可以序列化外部枚举好的,这不能回答我的问题。 – luketorjussen