2011-10-18 90 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