2011-10-18 13 views
10

Mam wyliczenie z zagnieżdżonym wyliczeniem (które chcę uczynić prywatnym), ale kiedy to zrobię, GWT powie mi, że zagnieżdżone wyliczenie nie jest widoczne i zgłasza wyjątek.Używanie wyliczenia zagnieżdżonego w GWT-RPC

Po usunięciu prywatnego modyfikatora z zagnieżdżonego wyliczenia, kod działa. Dlaczego GWT nie zezwala na prywatny modyfikator zagnieżdżonych wyliczeń? Czy jest w pobliżu praca?

+2

Czy próbowałeś zrobić to statycznie? –

+0

To jest naprawdę fajne! JLS (sekcja 8.9) wyraźnie mówi: "Zagnieżdżone typy wyrażeń są niejawnie statyczne. Dopuszczalne jest jawne zadeklarowanie zagnieżdżonego typu wyliczeniowego jako statycznego." Czy nie dotyczy to 'wyrażeń' zagnieżdżonych w 'wyliczeniach 'czy jest to mała wada w kompilatorze GWT? –

+0

... a kompilator GWT po prostu używa kompilatora Eclipse (ECJ) do analizy kodu źródłowego i budowania AST. Tak więc albo kompilator Eclipse ma błąd w nie wystawianiu wyliczenia jako statyczny, albo GWT ma błąd w nieodrzucaniu statycznej flagi dla zagnieżdżonego enum (chodziłem do ECJ, ale to naprawdę zależy od ich intencji; może być w trakcie projektu). –

Odpowiedz

2

Serializacja działa dobrze, przynajmniej z podanym przykładem. Wszystkie wyliczenia są traktowane serializowanie/deserializowane w następujący sposób (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()); 
} 

E.g. nie ma znaczenia, co jest używane w środku. Tylko porządek jest przekazywany przez sieć. Oznacza to, że jest jakiś problem w innym miejscu, GWT po prostu nie dba o to, co jest wewnątrz enum, ponieważ nie jest przekazywane przez sieć (enum powinno być niezmienne, nie ma potrzeby przenoszenia jego stanu). Myślę, że Twój problem może wyglądać mniej więcej tak:

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; 
     } 
    } 
} 

Ten przykład jest BARDZO inny niż poprzedni. Załóżmy, że OuterClass jest używany w usłudze GWT-RPC. Ponieważ NestedEnum jest wykorzystywany jako pole OuterClass, GWT musi utworzyć dla niego TypeSerializer. Ale ponieważ TypeSerializer jest osobną klasą, nie ma KAŻDEGO dostępu do NestedEnum (ponieważ jest prywatny). Tak więc kompilacja kończy się niepowodzeniem.

To w zasadzie jedyny przypadek, w którym twój przykład nie zadziała. W niektórych konkretnych wersjach GWT mogą występować błędy, ale jestem w 100% pewien, że twój przykład działa w GWT 2.2-2.4.

0

To prawdopodobnie ma związek z JavaScript. Jest możliwe/prawdopodobne, że w tłumaczeniu na JavaScript klasa zagnieżdżona jest zapisywana jako niezagnieżdżona. Dlatego jeśli jest prywatny, nic innego nie ma do niego dostępu. Obejście problemu polega na tym, aby nie było to prywatne, domyślny zakres powinien działać dobrze.

+0

To jest dobry punkt, nie myślałem o tym.Pomyślnie chciałbym, aby to było prywatne ... – luketorjussen

-2

Aby być typem klasy parametrów RPC, musi mieć pusty konstruktor do serializacji. Myślę więc, jeśli dodać

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

będzie działać!

+0

Problem polega na widoczności wewnętrznego wyliczenia.Może to serializować zewnętrzne wyliczenie To nie odpowiada na moje pytanie. – luketorjussen