2011-10-18 10 views
10

Tengo una enumeración con una enumeración anidada (que quiero hacer privada), pero cuando lo hago, GWT me dice que la enumeración anidada no está visible y arroja una excepción.Uso de una enumeración anidada en 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; 
    } 
} 

Si elimino el modificador privado de la enumeración anidada, entonces el código funciona. ¿Por qué GWT no permite el modificador privado para enumeraciones anidadas? ¿Hay alguna solución?

+2

¿Has intentado hacerlo estático? –

+0

Esto es realmente genial! El JLS (sección 8.9) dice explícitamente que "los tipos Enum anidados son implícitamente estáticos. Se permite declarar explícitamente que un tipo de enumeración anidado es estático". ¿Eso no se aplica a 'enum's anidado en' enum's o es un defecto menor en el compilador GWT? –

+0

... y el compilador GWT simplemente usa el compilador Eclipse (ECJ) para analizar el código fuente y crear AST. Entonces, o bien el compilador de Eclipse tiene un error al no exponer la enumeración como estática, o GWT tiene un error al no inferir la bandera estática de una enumeración anidada (yo elegiría ECJ, pero realmente depende de cuál sea su intención; podría ser por diseño). –

Respuesta

2

La serialización funciona bien, al menos con el ejemplo que ha proporcionado. Todo enumeraciones un conseguir serializado/deserializado en siguiente manera (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()); 
} 

P. ej No importa lo que se usa dentro. Solo el ordinal se pasa por la red. Significa que hay un problema en otro lugar, a GWT simplemente no le importa lo que hay dentro de la enumeración, porque no se transfiere a través de la red (la enumeración debe ser inmutable, no hay necesidad de transferir su estado). Creo que su problema podría ser algo como esto:

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

Este ejemplo es MUY diferente al anterior. Supongamos que OuterClass se usa en el servicio GWT-RPC. Como NestedEnum se usó como campo de OuterClass, GWT necesita crear un TypeSerializer para él. Pero dado que un TypeSerializer es una clase separada, no tiene CUALQUIER acceso al NestedEnum (ya que es privado). Entonces la compilación falla.

Este es básicamente el único caso cuando su ejemplo no funcionará. Puede haber algunos errores en algunas versiones específicas de GWT, pero estoy 100% seguro de que su ejemplo funciona en gwt 2.2-2.4.

0

Esto probablemente tiene que ver con JavaScript. Es posible/probable que en la traducción a JavaScript, la clase anidada se escriba como no anidada. Por lo tanto, si es privado, nada más tiene acceso a él. La solución es no hacerlo privado, el alcance predeterminado debería funcionar bien.

+0

Es un buen punto, no había pensado en eso. Idealmente, me gustaría que fuera privado ... – luketorjussen

-2

Para ser un tipo de clase de parámetro RPC, debe tener un constructor vacío para la serialización. Así que creo que, si se agrega

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

Se trabajará!

+0

El problema es con la visibilidad de la enumeración interna. Puede serializar la enumeración externa. bien. Esto no responde mi pregunta. – luketorjussen

Cuestiones relacionadas